OSDN Git Service

Phase 2 of read-only-plans project: restructure expression-tree nodes
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 12 Dec 2002 15:49:42 +0000 (15:49 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 12 Dec 2002 15:49:42 +0000 (15:49 +0000)
so that all executable expression nodes inherit from a common supertype
Expr.  This is somewhat of an exercise in code purity rather than any
real functional advance, but getting rid of the extra Oper or Func node
formerly used in each operator or function call should provide at least
a little space and speed improvement.
initdb forced by changes in stored-rules representation.

69 files changed:
src/backend/catalog/dependency.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/pg_proc.c
src/backend/commands/copy.c
src/backend/commands/explain.c
src/backend/commands/indexcmds.c
src/backend/commands/tablecmds.c
src/backend/commands/typecmds.c
src/backend/executor/execJunk.c
src/backend/executor/execMain.c
src/backend/executor/execProcnode.c
src/backend/executor/execQual.c
src/backend/executor/execTuples.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeSubplan.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/makefuncs.c
src/backend/nodes/nodeFuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/print.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/path/clausesel.c
src/backend/optimizer/path/costsize.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/path/orindxpath.c
src/backend/optimizer/path/pathkeys.c
src/backend/optimizer/path/tidpath.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/initsplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/prep/prepqual.c
src/backend/optimizer/prep/preptlist.c
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/tlist.c
src/backend/optimizer/util/var.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_clause.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_func.c
src/backend/parser/parse_node.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/rewrite/rewriteHandler.c
src/backend/rewrite/rewriteManip.c
src/backend/utils/adt/ri_triggers.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/selfuncs.c
src/include/catalog/catversion.h
src/include/executor/nodeSubplan.h
src/include/nodes/makefuncs.h
src/include/nodes/nodeFuncs.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/plannodes.h
src/include/nodes/primnodes.h
src/include/nodes/relation.h
src/include/optimizer/clauses.h
src/include/optimizer/paths.h
src/include/optimizer/planmain.h
src/pl/plpgsql/src/pl_exec.c

index bd837da..bcc92bf 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.17 2002/12/06 05:00:10 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.18 2002/12/12 15:49:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -806,25 +806,28 @@ find_expr_references_walker(Node *node,
                }
                return false;
        }
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr))
        {
-               Expr       *expr = (Expr *) node;
+               FuncExpr   *funcexpr = (FuncExpr *) node;
 
-               if (expr->opType == OP_EXPR ||
-                       expr->opType == DISTINCT_EXPR)
-               {
-                       Oper       *oper = (Oper *) expr->oper;
+               add_object_address(OCLASS_PROC, funcexpr->funcid, 0,
+                                                  &context->addrs);
+               /* fall through to examine arguments */
+       }
+       if (IsA(node, OpExpr))
+       {
+               OpExpr   *opexpr = (OpExpr *) node;
 
-                       add_object_address(OCLASS_OPERATOR, oper->opno, 0,
-                                                          &context->addrs);
-               }
-               else if (expr->opType == FUNC_EXPR)
-               {
-                       Func       *func = (Func *) expr->oper;
+               add_object_address(OCLASS_OPERATOR, opexpr->opno, 0,
+                                                  &context->addrs);
+               /* fall through to examine arguments */
+       }
+       if (IsA(node, DistinctExpr))
+       {
+               DistinctExpr   *distinctexpr = (DistinctExpr *) node;
 
-                       add_object_address(OCLASS_PROC, func->funcid, 0,
-                                                          &context->addrs);
-               }
+               add_object_address(OCLASS_OPERATOR, distinctexpr->opno, 0,
+                                                  &context->addrs);
                /* fall through to examine arguments */
        }
        if (IsA(node, Aggref))
index f8f667e..bd06827 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.235 2002/11/15 02:50:05 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.236 2002/12/12 15:49:23 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1603,11 +1603,6 @@ AddRelationRawConstraints(Relation rel,
                expr = (Node *) make_ands_implicit((Expr *) expr);
 
                /*
-                * Must fix opids in operator clauses.
-                */
-               fix_opids(expr);
-
-               /*
                 * OK, store it.
                 */
                StoreRelCheck(rel, ccname, nodeToString(expr));
@@ -1750,11 +1745,6 @@ cookDefault(ParseState *pstate,
         */
        expr = eval_const_expressions(expr);
 
-       /*
-        * Must fix opids, in case any operators remain...
-        */
-       fix_opids(expr);
-
        return (expr);
 }
 
index cdac597..c11bd5b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.205 2002/11/13 00:39:46 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.206 2002/12/12 15:49:24 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -41,6 +41,7 @@
 #include "executor/executor.h"
 #include "miscadmin.h"
 #include "optimizer/clauses.h"
+#include "optimizer/planmain.h"
 #include "optimizer/prep.h"
 #include "parser/parse_func.h"
 #include "storage/sinval.h"
@@ -919,6 +920,7 @@ BuildIndexInfo(Form_pg_index indexStruct)
                predString = DatumGetCString(DirectFunctionCall1(textout,
                                                                PointerGetDatum(&indexStruct->indpred)));
                ii->ii_Predicate = stringToNode(predString);
+               fix_opfuncids((Node *) ii->ii_Predicate);
                pfree(predString);
        }
        else
index b915a02..14f3734 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.94 2002/09/18 21:35:20 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.95 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -424,7 +424,7 @@ checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
                        } while (attr->attisdropped);
                        rellogcols++;
 
-                       tletype = exprType(tle->expr);
+                       tletype = exprType((Node *) tle->expr);
                        atttype = attr->atttypid;
                        if (!IsBinaryCoercible(tletype, atttype))
                                elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
index 45749ab..4158633 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.184 2002/12/01 18:14:22 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.185 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,6 +35,7 @@
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
+#include "optimizer/planmain.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_relation.h"
 #include "rewrite/rewriteHandler.h"
@@ -839,6 +840,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
                        defexprs[num_defaults] = build_column_default(rel, i + 1);
                        if (defexprs[num_defaults] != NULL)
                        {
+                               fix_opfuncids(defexprs[num_defaults]);
                                defmap[num_defaults] = i;
                                num_defaults++;
                        }
@@ -869,6 +871,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
                        /* check whether any constraints actually found */
                        if (node != (Node *) prm)
                        {
+                               fix_opfuncids(node);
                                constraintexprs[i] = node;
                                hasConstraints = true;
                        }
index 0b5efaa..c587765 100644 (file)
@@ -5,7 +5,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.95 2002/12/06 19:28:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.96 2002/12/12 15:49:24 tgl Exp $
  *
  */
 
@@ -417,20 +417,27 @@ explain_outNode(StringInfo str,
                        {
                                RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
                                                                                          es->rtable);
-                               Expr       *expr;
-                               Func       *funcnode;
-                               Oid                     funcid;
                                char       *proname;
 
                                /* Assert it's on a RangeFunction */
                                Assert(rte->rtekind == RTE_FUNCTION);
 
-                               expr = (Expr *) rte->funcexpr;
-                               funcnode = (Func *) expr->oper;
-                               funcid = funcnode->funcid;
-
-                               /* We only show the func name, not schema name */
-                               proname = get_func_name(funcid);
+                               /*
+                                * If the expression is still a function call, we can get
+                                * the real name of the function.  Otherwise, punt (this
+                                * can happen if the optimizer simplified away the function
+                                * call, for example).
+                                */
+                               if (rte->funcexpr && IsA(rte->funcexpr, FuncExpr))
+                               {
+                                       FuncExpr   *funcexpr = (FuncExpr *) rte->funcexpr;
+                                       Oid                     funcid = funcexpr->funcid;
+
+                                       /* We only show the func name, not schema name */
+                                       proname = get_func_name(funcid);
+                               }
+                               else
+                                       proname = rte->eref->aliasname;
 
                                appendStringInfo(str, " on %s",
                                                                 quote_identifier(proname));
@@ -583,7 +590,7 @@ explain_outNode(StringInfo str,
                appendStringInfo(str, "  InitPlan\n");
                foreach(lst, plan->initPlan)
                {
-                       SubPlan    *subplan = (SubPlan *) lfirst(lst);
+                       SubPlanExpr  *subplan = (SubPlanExpr *) lfirst(lst);
                        SubPlanState *subplanstate = (SubPlanState *) lfirst(pslist);
 
                        es->rtable = subplan->rtable;
@@ -683,7 +690,7 @@ explain_outNode(StringInfo str,
                foreach(lst, planstate->subPlan)
                {
                        SubPlanState *sps = (SubPlanState *) lfirst(lst);
-                       SubPlan *sp = (SubPlan *) sps->ps.plan;
+                       SubPlanExpr *sp = (SubPlanExpr *) sps->ps.plan;
 
                        es->rtable = sp->rtable;
                        for (i = 0; i < indent; i++)
@@ -870,7 +877,7 @@ show_sort_keys(List *tlist, int nkeys, const char *qlabel,
                        if (target->resdom->reskey == keyno)
                        {
                                /* Deparse the expression, showing any top-level cast */
-                               exprstr = deparse_expression(target->expr, context,
+                               exprstr = deparse_expression((Node *) target->expr, context,
                                                                                         useprefix, true);
                                /* And add to str */
                                if (keyno > 1)
index 5447780..d6ccdb9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.92 2002/10/21 22:06:19 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.93 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -159,10 +159,10 @@ DefineIndex(RangeVar *heapRelation,
         * While we are at it, we reduce it to a canonical (CNF or DNF) form
         * to simplify the task of proving implications.
         */
-       if (predicate != NULL && rangetable != NIL)
+       if (predicate)
        {
                cnfPred = canonicalize_qual((Expr *) copyObject(predicate), true);
-               fix_opids((Node *) cnfPred);
+               fix_opfuncids((Node *) cnfPred);
                CheckPredicate(cnfPred, rangetable, relationId);
        }
 
index 8da1de5..1968773 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.57 2002/11/23 18:26:45 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.58 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2723,7 +2723,7 @@ AlterTableAddCheckConstraint(Relation rel, Constraint *constr)
        /*
         * We need to make a parse state and range
         * table to allow us to transformExpr and
-        * fix_opids to get a version of the
+        * fix_opfuncids to get a version of the
         * expression we can pass to ExecQual
         */
        pstate = make_parsestate(NULL);
@@ -2764,8 +2764,8 @@ AlterTableAddCheckConstraint(Relation rel, Constraint *constr)
         */
        expr = eval_const_expressions(expr);
 
-       /* And fix the opids */
-       fix_opids(expr);
+       /* And fix the opfuncids */
+       fix_opfuncids(expr);
 
        qual = makeList1(expr);
 
index d5260ad..e16942a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.21 2002/12/09 20:31:05 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.22 2002/12/12 15:49:24 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -1341,7 +1341,9 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
         * the constraint is being added to.
         */
        expr = stringToNode(ccbin);
+       fix_opfuncids(expr);
        rels = get_rels_with_domain(domainoid);
+
        foreach (rt, rels)
        {
                Relation        typrel;
@@ -1522,7 +1524,7 @@ domainPermissionCheck(HeapTuple tup, TypeName *typename)
 
 
 /*
- *
+ * domainAddConstraint
  */
 char *
 domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
@@ -1601,21 +1603,20 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
        expr = eval_const_expressions(expr);
 
        /*
-        * Must fix opids in operator clauses.
+        * Convert to string form for storage.
         */
-       fix_opids(expr);
-
        ccbin = nodeToString(expr);
 
        /*
-        * Deparse it.  Since VARNOs aren't allowed in domain
-        * constraints, relation context isn't required as anything
-        * other than a shell.
+        * Deparse it to produce text for consrc.
+        *
+        * Since VARNOs aren't allowed in domain constraints, relation context
+        * isn't required as anything other than a shell.
         */
        ccsrc = deparse_expression(expr,
-                               deparse_context_for(domainName,
-                                                                       InvalidOid),
-                                                                  false, false);
+                                                          deparse_context_for(domainName,
+                                                                                                  InvalidOid),
+                                                          false, false);
 
        /* Write the constraint */
        CreateConstraintEntry(constr->name,             /* Constraint Name */
index 761ff40..edaf7aa 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.32 2002/09/04 20:31:17 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.33 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -77,7 +77,7 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType,
        bool            resjunk;
        AttrNumber      cleanResno;
        AttrNumber *cleanMap;
-       Node       *expr;
+       Expr       *expr;
 
        /*
         * Make a memory context that will hold the JunkFilter as well as all
@@ -104,65 +104,23 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType,
        {
                TargetEntry *rtarget = lfirst(t);
 
-               if (rtarget->resdom != NULL)
-               {
-                       resdom = rtarget->resdom;
-                       expr = rtarget->expr;
-                       resjunk = resdom->resjunk;
-                       if (!resjunk)
-                       {
-                               /*
-                                * make a copy of the resdom node, changing its resno.
-                                */
-                               cleanResdom = (Resdom *) copyObject(resdom);
-                               cleanResdom->resno = cleanResno;
-                               cleanResno++;
-
-                               /*
-                                * create a new target list entry
-                                */
-                               tle = makeTargetEntry(cleanResdom, expr);
-                               cleanTargetList = lappend(cleanTargetList, tle);
-                       }
-               }
-               else
+               resdom = rtarget->resdom;
+               expr = rtarget->expr;
+               resjunk = resdom->resjunk;
+               if (!resjunk)
                {
-#ifdef SETS_FIXED
-                       List       *fjListP;
-                       Fjoin      *cleanFjoin;
-                       List       *cleanFjList;
-                       List       *fjList = lfirst(t);
-                       Fjoin      *fjNode = (Fjoin *) tl_node(fjList);
-
-                       cleanFjoin = (Fjoin) copyObject((Node) fjNode);
-                       cleanFjList = makeList1(cleanFjoin);
-
-                       resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
-                       expr = lsecond(get_fj_innerNode(fjNode));
-                       cleanResdom = (Resdom) copyObject((Node) resdom);
-                       set_resno(cleanResdom, cleanResno);
+                       /*
+                        * make a copy of the resdom node, changing its resno.
+                        */
+                       cleanResdom = (Resdom *) copyObject(resdom);
+                       cleanResdom->resno = cleanResno;
                        cleanResno++;
-                       tle = (List) makeTargetEntry(cleanResdom, (Node *) expr);
-                       set_fj_innerNode(cleanFjoin, tle);
-
-                       foreach(fjListP, lnext(fjList))
-                       {
-                               TargetEntry *tle = lfirst(fjListP);
 
-                               resdom = tle->resdom;
-                               expr = tle->expr;
-                               cleanResdom = (Resdom *) copyObject((Node) resdom);
-                               cleanResno++;
-                               cleanResdom->Resno = cleanResno;
-
-                               /*
-                                * create a new target list entry
-                                */
-                               tle = (List) makeTargetEntry(cleanResdom, (Node *) expr);
-                               cleanFjList = lappend(cleanFjList, tle);
-                       }
-                       lappend(cleanTargetList, cleanFjList);
-#endif
+                       /*
+                        * create a new target list entry
+                        */
+                       tle = makeTargetEntry(cleanResdom, expr);
+                       cleanTargetList = lappend(cleanTargetList, tle);
                }
        }
 
@@ -192,41 +150,12 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType,
                {
                        TargetEntry *tle = lfirst(t);
 
-                       if (tle->resdom != NULL)
-                       {
-                               resdom = tle->resdom;
-                               expr = tle->expr;
-                               resjunk = resdom->resjunk;
-                               if (!resjunk)
-                               {
-                                       cleanMap[cleanResno - 1] = resdom->resno;
-                                       cleanResno++;
-                               }
-                       }
-                       else
+                       resdom = tle->resdom;
+                       resjunk = resdom->resjunk;
+                       if (!resjunk)
                        {
-#ifdef SETS_FIXED
-                               List            fjListP;
-                               List            fjList = lfirst(t);
-                               Fjoin           fjNode = (Fjoin) lfirst(fjList);
-
-                               /* what the hell is this????? */
-                               resdom = (Resdom) lfirst(get_fj_innerNode(fjNode));
-#endif
-
-                               cleanMap[cleanResno - 1] = tle->resdom->resno;
+                               cleanMap[cleanResno - 1] = resdom->resno;
                                cleanResno++;
-
-#ifdef SETS_FIXED
-                               foreach(fjListP, lnext(fjList))
-                               {
-                                       TargetEntry *tle = lfirst(fjListP);
-
-                                       resdom = tle->resdom;
-                                       cleanMap[cleanResno - 1] = resdom->resno;
-                                       cleanResno++;
-                               }
-#endif
                        }
                }
        }
index 15d47df..abd099c 100644 (file)
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.190 2002/12/05 15:50:30 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.191 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,6 +40,7 @@
 #include "executor/execdebug.h"
 #include "executor/execdefs.h"
 #include "miscadmin.h"
+#include "optimizer/planmain.h"
 #include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "utils/acl.h"
@@ -1541,6 +1542,7 @@ ExecRelCheck(ResultRelInfo *resultRelInfo,
                for (i = 0; i < ncheck; i++)
                {
                        qual = (List *) stringToNode(check[i].ccbin);
+                       fix_opfuncids((Node *) qual);
                        resultRelInfo->ri_ConstraintExprs[i] = qual;
                }
                MemoryContextSwitchTo(oldContext);
index 2db4a14..680a6da 100644 (file)
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.31 2002/12/05 15:50:31 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.32 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -228,9 +228,9 @@ ExecInitNode(Plan *node, EState *estate)
        subps = NIL;
        foreach(subp, node->initPlan)
        {
-               SubPlan    *subplan = (SubPlan *) lfirst(subp);
+               SubPlanExpr *subplan = (SubPlanExpr *) lfirst(subp);
 
-               Assert(IsA(subplan, SubPlan));
+               Assert(IsA(subplan, SubPlanExpr));
                subps = lappend(subps, ExecInitSubPlan(subplan, estate));
        }
        result->initPlan = subps;
@@ -242,9 +242,9 @@ ExecInitNode(Plan *node, EState *estate)
        subps = NIL;
        foreach(subp, result->subPlan)
        {
-               SubPlan    *subplan = (SubPlan *) lfirst(subp);
+               SubPlanExpr *subplan = (SubPlanExpr *) lfirst(subp);
 
-               Assert(IsA(subplan, SubPlan));
+               Assert(IsA(subplan, SubPlanExpr));
                subps = lappend(subps, ExecInitSubPlan(subplan, estate));
        }
        result->subPlan = subps;
index 2392981..d96e983 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.116 2002/12/06 05:00:16 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.117 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,17 +53,20 @@ static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext,
 static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
                                 bool *isNull, ExprDoneCond *isDone);
 static Datum ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalOper(Expr *opClause, ExprContext *econtext,
+static Datum ExecEvalOper(OpExpr *op, ExprContext *econtext,
                         bool *isNull, ExprDoneCond *isDone);
-static Datum ExecEvalDistinct(Expr *opClause, ExprContext *econtext,
+static Datum ExecEvalDistinct(DistinctExpr *op, ExprContext *econtext,
                                 bool *isNull, ExprDoneCond *isDone);
-static Datum ExecEvalFunc(Expr *funcClause, ExprContext *econtext,
+static Datum ExecEvalFunc(FuncExpr *func, ExprContext *econtext,
                         bool *isNull, ExprDoneCond *isDone);
 static ExprDoneCond ExecEvalFuncArgs(FunctionCallInfo fcinfo,
                                 List *argList, ExprContext *econtext);
-static Datum ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
-static Datum ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull);
+static Datum ExecEvalNot(BoolExpr *notclause, ExprContext *econtext,
+                                                bool *isNull);
+static Datum ExecEvalOr(BoolExpr *orExpr, ExprContext *econtext,
+                                               bool *isNull);
+static Datum ExecEvalAnd(BoolExpr *andExpr, ExprContext *econtext,
+                                                bool *isNull);
 static Datum ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
                         bool *isNull, ExprDoneCond *isDone);
 static Datum ExecEvalNullTest(NullTest *ntest, ExprContext *econtext,
@@ -122,7 +125,7 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
        if (arrayRef->refexpr != NULL)
        {
                array_source = (ArrayType *)
-                       DatumGetPointer(ExecEvalExpr(arrayRef->refexpr,
+                       DatumGetPointer(ExecEvalExpr((Node *) arrayRef->refexpr,
                                                                                 econtext,
                                                                                 isNull,
                                                                                 isDone));
@@ -203,7 +206,7 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
 
        if (isAssignment)
        {
-               Datum           sourceData = ExecEvalExpr(arrayRef->refassgnexpr,
+               Datum           sourceData = ExecEvalExpr((Node *) arrayRef->refassgnexpr,
                                                                                          econtext,
                                                                                          isNull,
                                                                                          NULL);
@@ -839,7 +842,7 @@ ExecMakeTableFunctionResult(Node *funcexpr,
        bool            returnsTuple = false;
 
        /*
-        * Normally the passed expression tree will be a FUNC_EXPR, since the
+        * Normally the passed expression tree will be a FuncExpr, since the
         * grammar only allows a function call at the top level of a table
         * function reference.  However, if the function doesn't return set then
         * the planner might have replaced the function call via constant-folding
@@ -848,11 +851,9 @@ ExecMakeTableFunctionResult(Node *funcexpr,
         * we don't get a chance to pass a special ReturnSetInfo to any functions
         * buried in the expression.
         */
-       if (funcexpr &&
-               IsA(funcexpr, Expr) &&
-               ((Expr *) funcexpr)->opType == FUNC_EXPR)
+       if (funcexpr && IsA(funcexpr, FuncExpr))
        {
-               Func       *func;
+               FuncExpr   *func = (FuncExpr *) funcexpr;
                List       *argList;
                FunctionCachePtr fcache;
                ExprDoneCond argDone;
@@ -862,13 +863,12 @@ ExecMakeTableFunctionResult(Node *funcexpr,
                 */
                direct_function_call = true;
 
-               funcrettype = ((Expr *) funcexpr)->typeOid;
-               func = (Func *) ((Expr *) funcexpr)->oper;
-               argList = ((Expr *) funcexpr)->args;
+               funcrettype = func->funcresulttype;
+               argList = func->args;
 
                /*
-                * get the fcache from the Func node. If it is NULL, then initialize
-                * it
+                * get the fcache from the FuncExpr node. If it is NULL, then
+                * initialize it
                 */
                fcache = func->func_fcache;
                if (fcache == NULL)
@@ -1102,12 +1102,11 @@ ExecMakeTableFunctionResult(Node *funcexpr,
  * ----------------------------------------------------------------
  */
 static Datum
-ExecEvalOper(Expr *opClause,
+ExecEvalOper(OpExpr *op,
                         ExprContext *econtext,
                         bool *isNull,
                         ExprDoneCond *isDone)
 {
-       Oper       *op;
        List       *argList;
        FunctionCachePtr fcache;
 
@@ -1117,17 +1116,16 @@ ExecEvalOper(Expr *opClause,
         * arguments and returns the result of calling the function on the
         * evaluated arguments.
         */
-       op = (Oper *) opClause->oper;
-       argList = opClause->args;
+       argList = op->args;
 
        /*
-        * get the fcache from the Oper node. If it is NULL, then initialize
+        * get the fcache from the OpExpr node. If it is NULL, then initialize
         * it
         */
        fcache = op->op_fcache;
        if (fcache == NULL)
        {
-               fcache = init_fcache(op->opid, length(argList),
+               fcache = init_fcache(op->opfuncid, length(argList),
                                                         econtext->ecxt_per_query_memory);
                op->op_fcache = fcache;
        }
@@ -1142,12 +1140,11 @@ ExecEvalOper(Expr *opClause,
  */
 
 static Datum
-ExecEvalFunc(Expr *funcClause,
+ExecEvalFunc(FuncExpr *func,
                         ExprContext *econtext,
                         bool *isNull,
                         ExprDoneCond *isDone)
 {
-       Func       *func;
        List       *argList;
        FunctionCachePtr fcache;
 
@@ -1159,11 +1156,10 @@ ExecEvalFunc(Expr *funcClause,
         *
         * this is nearly identical to the ExecEvalOper code.
         */
-       func = (Func *) funcClause->oper;
-       argList = funcClause->args;
+       argList = func->args;
 
        /*
-        * get the fcache from the Func node. If it is NULL, then initialize
+        * get the fcache from the FuncExpr node. If it is NULL, then initialize
         * it
         */
        fcache = func->func_fcache;
@@ -1190,7 +1186,7 @@ ExecEvalFunc(Expr *funcClause,
  * ----------------------------------------------------------------
  */
 static Datum
-ExecEvalDistinct(Expr *opClause,
+ExecEvalDistinct(DistinctExpr *op,
                                 ExprContext *econtext,
                                 bool *isNull,
                                 ExprDoneCond *isDone)
@@ -1199,23 +1195,21 @@ ExecEvalDistinct(Expr *opClause,
        FunctionCachePtr fcache;
        FunctionCallInfoData fcinfo;
        ExprDoneCond argDone;
-       Oper       *op;
        List       *argList;
 
        /*
-        * extract info from opClause
+        * extract info from op
         */
-       op = (Oper *) opClause->oper;
-       argList = opClause->args;
+       argList = op->args;
 
        /*
-        * get the fcache from the Oper node. If it is NULL, then initialize
-        * it
+        * get the fcache from the DistinctExpr node. If it is NULL, then
+        * initialize it
         */
        fcache = op->op_fcache;
        if (fcache == NULL)
        {
-               fcache = init_fcache(op->opid, length(argList),
+               fcache = init_fcache(op->opfuncid, length(argList),
                                                         econtext->ecxt_per_query_memory);
                op->op_fcache = fcache;
        }
@@ -1256,8 +1250,7 @@ ExecEvalDistinct(Expr *opClause,
  *             ExecEvalOr
  *             ExecEvalAnd
  *
- *             Evaluate boolean expressions.  Evaluation of 'or' is
- *             short-circuited when the first true (or null) value is found.
+ *             Evaluate boolean expressions, with appropriate short-circuiting.
  *
  *             The query planner reformulates clause expressions in the
  *             qualification to conjunctive normal form.  If we ever get
@@ -1268,7 +1261,7 @@ ExecEvalDistinct(Expr *opClause,
  * ----------------------------------------------------------------
  */
 static Datum
-ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
+ExecEvalNot(BoolExpr *notclause, ExprContext *econtext, bool *isNull)
 {
        Node       *clause;
        Datum           expr_value;
@@ -1296,7 +1289,7 @@ ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
  * ----------------------------------------------------------------
  */
 static Datum
-ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
+ExecEvalOr(BoolExpr *orExpr, ExprContext *econtext, bool *isNull)
 {
        List       *clauses;
        List       *clause;
@@ -1344,7 +1337,7 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
  * ----------------------------------------------------------------
  */
 static Datum
-ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
+ExecEvalAnd(BoolExpr *andExpr, ExprContext *econtext, bool *isNull)
 {
        List       *clauses;
        List       *clause;
@@ -1409,7 +1402,7 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
        {
                CaseWhen   *wclause = lfirst(clause);
 
-               clause_value = ExecEvalExpr(wclause->expr,
+               clause_value = ExecEvalExpr((Node *) wclause->expr,
                                                                        econtext,
                                                                        isNull,
                                                                        NULL);
@@ -1421,7 +1414,7 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
                 */
                if (DatumGetBool(clause_value) && !*isNull)
                {
-                       return ExecEvalExpr(wclause->result,
+                       return ExecEvalExpr((Node *) wclause->result,
                                                                econtext,
                                                                isNull,
                                                                isDone);
@@ -1430,7 +1423,7 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext,
 
        if (caseExpr->defresult)
        {
-               return ExecEvalExpr(caseExpr->defresult,
+               return ExecEvalExpr((Node *) caseExpr->defresult,
                                                        econtext,
                                                        isNull,
                                                        isDone);
@@ -1454,7 +1447,7 @@ ExecEvalNullTest(NullTest *ntest,
 {
        Datum           result;
 
-       result = ExecEvalExpr(ntest->arg, econtext, isNull, isDone);
+       result = ExecEvalExpr((Node *) ntest->arg, econtext, isNull, isDone);
        switch (ntest->nulltesttype)
        {
                case IS_NULL:
@@ -1494,7 +1487,7 @@ ExecEvalBooleanTest(BooleanTest *btest,
 {
        Datum           result;
 
-       result = ExecEvalExpr(btest->arg, econtext, isNull, isDone);
+       result = ExecEvalExpr((Node *) btest->arg, econtext, isNull, isDone);
        switch (btest->booltesttype)
        {
                case IS_TRUE:
@@ -1590,7 +1583,7 @@ ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext,
 {
        Datum           result;
 
-       result = ExecEvalExpr(constraint->arg, econtext, isNull, isDone);
+       result = ExecEvalExpr((Node *) constraint->arg, econtext, isNull, isDone);
 
        switch (constraint->testtype)
        {
@@ -1607,7 +1600,7 @@ ExecEvalConstraintTest(ConstraintTest *constraint, ExprContext *econtext,
                                econtext->domainValue_datum = result;
                                econtext->domainValue_isNull = *isNull;
 
-                               conResult = ExecEvalExpr(constraint->check_expr, econtext, isNull, isDone);
+                               conResult = ExecEvalExpr((Node *) constraint->check_expr, econtext, isNull, isDone);
 
                                if (!DatumGetBool(conResult))
                                        elog(ERROR, "ExecEvalConstraintTest: Domain %s constraint %s failed",
@@ -1638,7 +1631,7 @@ ExecEvalFieldSelect(FieldSelect *fselect,
        Datum           result;
        TupleTableSlot *resSlot;
 
-       result = ExecEvalExpr(fselect->arg, econtext, isNull, isDone);
+       result = ExecEvalExpr((Node *) fselect->arg, econtext, isNull, isDone);
        if (*isNull)
                return result;
        resSlot = (TupleTableSlot *) DatumGetPointer(result);
@@ -1738,47 +1731,48 @@ ExecEvalExpr(Node *expression,
                                                                                isNull,
                                                                                isDone);
                        break;
-               case T_Expr:
+               case T_FuncExpr:
+                       retDatum = ExecEvalFunc((FuncExpr *) expression, econtext,
+                                                                       isNull, isDone);
+                       break;
+               case T_OpExpr:
+                       retDatum = ExecEvalOper((OpExpr *) expression, econtext,
+                                                                       isNull, isDone);
+                       break;
+               case T_DistinctExpr:
+                       retDatum = ExecEvalDistinct((DistinctExpr *) expression, econtext,
+                                                                               isNull, isDone);
+                       break;
+               case T_BoolExpr:
                        {
-                               Expr       *expr = (Expr *) expression;
+                               BoolExpr   *expr = (BoolExpr *) expression;
 
-                               switch (expr->opType)
+                               switch (expr->boolop)
                                {
-                                       case OP_EXPR:
-                                               retDatum = ExecEvalOper(expr, econtext,
-                                                                                               isNull, isDone);
-                                               break;
-                                       case FUNC_EXPR:
-                                               retDatum = ExecEvalFunc(expr, econtext,
-                                                                                               isNull, isDone);
+                                       case AND_EXPR:
+                                               retDatum = ExecEvalAnd(expr, econtext, isNull);
                                                break;
                                        case OR_EXPR:
                                                retDatum = ExecEvalOr(expr, econtext, isNull);
                                                break;
-                                       case AND_EXPR:
-                                               retDatum = ExecEvalAnd(expr, econtext, isNull);
-                                               break;
                                        case NOT_EXPR:
                                                retDatum = ExecEvalNot(expr, econtext, isNull);
                                                break;
-                                       case DISTINCT_EXPR:
-                                               retDatum = ExecEvalDistinct(expr, econtext,
-                                                                                                       isNull, isDone);
-                                               break;
-                                       case SUBPLAN_EXPR:
-                                               /* XXX temporary hack to find exec state node */
-                                               retDatum = ExecSubPlan(((SubPlan *) expr->oper)->pstate,
-                                                                                          expr->args, econtext,
-                                                                                          isNull);
-                                               break;
                                        default:
-                                               elog(ERROR, "ExecEvalExpr: unknown expression type %d",
-                                                        expr->opType);
+                                               elog(ERROR, "ExecEvalExpr: unknown boolop %d",
+                                                        expr->boolop);
                                                retDatum = 0;   /* keep compiler quiet */
                                                break;
                                }
                                break;
                        }
+               case T_SubPlanExpr:
+                       /* XXX temporary hack to find exec state node */
+                       retDatum = ExecSubPlan(((SubPlanExpr *) expression)->pstate,
+                                                                  ((SubPlanExpr *) expression)->args,
+                                                                  econtext,
+                                                                  isNull);
+                       break;
                case T_FieldSelect:
                        retDatum = ExecEvalFieldSelect((FieldSelect *) expression,
                                                                                   econtext,
@@ -1786,7 +1780,7 @@ ExecEvalExpr(Node *expression,
                                                                                   isDone);
                        break;
                case T_RelabelType:
-                       retDatum = ExecEvalExpr(((RelabelType *) expression)->arg,
+                       retDatum = ExecEvalExpr((Node *) ((RelabelType *) expression)->arg,
                                                                        econtext,
                                                                        isNull,
                                                                        isDone);
@@ -1861,7 +1855,7 @@ ExecEvalExprSwitchContext(Node *expression,
  *
  * Soon this will generate an expression state tree paralleling the given
  * expression tree.  Right now, it just searches the expression tree for
- * Aggref and SubPlan nodes.
+ * Aggref and SubPlanExpr nodes.
  */
 Node *
 ExecInitExpr(Node *node, PlanState *parent)
@@ -1887,7 +1881,7 @@ ExecInitExpr(Node *node, PlanState *parent)
                                aggstate->aggs = lcons(node, aggstate->aggs);
                                naggs = ++aggstate->numaggs;
 
-                               ExecInitExpr(((Aggref *) node)->target, parent);
+                               ExecInitExpr((Node *) ((Aggref *) node)->target, parent);
 
                                /*
                                 * Complain if the aggregate's argument contains any
@@ -1907,64 +1901,67 @@ ExecInitExpr(Node *node, PlanState *parent)
 
                                ExecInitExpr((Node *) aref->refupperindexpr, parent);
                                ExecInitExpr((Node *) aref->reflowerindexpr, parent);
-                               ExecInitExpr(aref->refexpr, parent);
-                               ExecInitExpr(aref->refassgnexpr, parent);
+                               ExecInitExpr((Node *) aref->refexpr, parent);
+                               ExecInitExpr((Node *) aref->refassgnexpr, parent);
                        }
                        break;
-               case T_Expr:
+               case T_FuncExpr:
                        {
-                               Expr       *expr = (Expr *) node;
+                               FuncExpr   *funcexpr = (FuncExpr *) node;
 
-                               switch (expr->opType)
-                               {
-                                       case OP_EXPR:
-                                               break;
-                                       case FUNC_EXPR:
-                                               break;
-                                       case OR_EXPR:
-                                               break;
-                                       case AND_EXPR:
-                                               break;
-                                       case NOT_EXPR:
-                                               break;
-                                       case DISTINCT_EXPR:
-                                               break;
-                                       case SUBPLAN_EXPR:
-                                               if (parent)
-                                               {
-                                                       SubLink *sublink = ((SubPlan *) expr->oper)->sublink;
+                               ExecInitExpr((Node *) funcexpr->args, parent);
+                       }
+                       break;
+               case T_OpExpr:
+                       {
+                               OpExpr   *opexpr = (OpExpr *) node;
 
-                                                       /*
-                                                        * Here we just add the SubPlan nodes to
-                                                        * parent->subPlan.  Later they will be expanded
-                                                        * to SubPlanState nodes.
-                                                        */
-                                                       parent->subPlan = lcons(expr->oper,
-                                                                                                       parent->subPlan);
-
-                                                       /* Must recurse into oper list too */
-                                                       Assert(IsA(sublink, SubLink));
-                                                       if (sublink->lefthand)
-                                                               elog(ERROR, "ExecInitExpr: sublink has not been transformed");
-                                                       ExecInitExpr((Node *) sublink->oper, parent);
-                                               }
-                                               else
-                                                       elog(ERROR, "ExecInitExpr: SubPlan not expected here");
-                                               break;
-                                       default:
-                                               elog(ERROR, "ExecInitExpr: unknown expression type %d",
-                                                        expr->opType);
-                                               break;
-                               }
-                               /* for all Expr node types, examine args list */
-                               ExecInitExpr((Node *) expr->args, parent);
+                               ExecInitExpr((Node *) opexpr->args, parent);
+                       }
+                       break;
+               case T_DistinctExpr:
+                       {
+                               DistinctExpr   *distinctexpr = (DistinctExpr *) node;
+
+                               ExecInitExpr((Node *) distinctexpr->args, parent);
+                       }
+                       break;
+               case T_BoolExpr:
+                       {
+                               BoolExpr   *boolexpr = (BoolExpr *) node;
+
+                               ExecInitExpr((Node *) boolexpr->args, parent);
+                       }
+                       break;
+               case T_SubPlanExpr:
+                       {
+                               SubPlanExpr *subplanexpr = (SubPlanExpr *) node;
+                               SubLink *sublink = subplanexpr->sublink;
+
+                               Assert(IsA(sublink, SubLink));
+                               if (!parent)
+                                       elog(ERROR, "ExecInitExpr: SubPlanExpr not expected here");
+
+                               /*
+                                * Here we just add the SubPlanExpr nodes to
+                                * parent->subPlan.  Later they will be expanded
+                                * to SubPlanState nodes.
+                                */
+                               parent->subPlan = lcons(subplanexpr, parent->subPlan);
+
+                               /* Must recurse into oper list too */
+                               if (sublink->lefthand)
+                                       elog(ERROR, "ExecInitExpr: sublink has not been transformed");
+                               ExecInitExpr((Node *) sublink->oper, parent);
+
+                               ExecInitExpr((Node *) subplanexpr->args, parent);
                        }
                        break;
                case T_FieldSelect:
-                       ExecInitExpr(((FieldSelect *) node)->arg, parent);
+                       ExecInitExpr((Node *) ((FieldSelect *) node)->arg, parent);
                        break;
                case T_RelabelType:
-                       ExecInitExpr(((RelabelType *) node)->arg, parent);
+                       ExecInitExpr((Node *) ((RelabelType *) node)->arg, parent);
                        break;
                case T_CaseExpr:
                        {
@@ -1975,35 +1972,35 @@ ExecInitExpr(Node *node, PlanState *parent)
                                        CaseWhen   *when = (CaseWhen *) lfirst(temp);
 
                                        Assert(IsA(when, CaseWhen));
-                                       ExecInitExpr(when->expr, parent);
-                                       ExecInitExpr(when->result, parent);
+                                       ExecInitExpr((Node *) when->expr, parent);
+                                       ExecInitExpr((Node *) when->result, parent);
                                }
                                /* caseexpr->arg should be null, but we'll check it anyway */
-                               ExecInitExpr(caseexpr->arg, parent);
-                               ExecInitExpr(caseexpr->defresult, parent);
+                               ExecInitExpr((Node *) caseexpr->arg, parent);
+                               ExecInitExpr((Node *) caseexpr->defresult, parent);
                        }
                        break;
                case T_NullTest:
-                       ExecInitExpr(((NullTest *) node)->arg, parent);
+                       ExecInitExpr((Node *) ((NullTest *) node)->arg, parent);
                        break;
                case T_BooleanTest:
-                       ExecInitExpr(((BooleanTest *) node)->arg, parent);
+                       ExecInitExpr((Node *) ((BooleanTest *) node)->arg, parent);
                        break;
                case T_ConstraintTest:
-                       ExecInitExpr(((ConstraintTest *) node)->arg, parent);
-                       ExecInitExpr(((ConstraintTest *) node)->check_expr, parent);
+                       ExecInitExpr((Node *) ((ConstraintTest *) node)->arg, parent);
+                       ExecInitExpr((Node *) ((ConstraintTest *) node)->check_expr, parent);
                        break;
                case T_ConstraintTestValue:
                        break;
+               case T_TargetEntry:
+                       ExecInitExpr((Node *) ((TargetEntry *) node)->expr, parent);
+                       break;
                case T_List:
                        foreach(temp, (List *) node)
                        {
                                ExecInitExpr((Node *) lfirst(temp), parent);
                        }
                        break;
-               case T_TargetEntry:
-                       ExecInitExpr(((TargetEntry *) node)->expr, parent);
-                       break;
                default:
                        elog(ERROR, "ExecInitExpr: unknown expression type %d",
                                 nodeTag(node));
@@ -2119,19 +2116,8 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
 int
 ExecTargetListLength(List *targetlist)
 {
-       int                     len = 0;
-       List       *tl;
-
-       foreach(tl, targetlist)
-       {
-               TargetEntry *curTle = (TargetEntry *) lfirst(tl);
-
-               if (curTle->resdom != NULL)
-                       len++;
-               else
-                       len += curTle->fjoin->fj_nNodes;
-       }
-       return len;
+       /* This used to be more complex, but fjoins are dead */
+       return length(targetlist);
 }
 
 /*
@@ -2147,13 +2133,8 @@ ExecCleanTargetListLength(List *targetlist)
        {
                TargetEntry *curTle = (TargetEntry *) lfirst(tl);
 
-               if (curTle->resdom != NULL)
-               {
-                       if (!curTle->resdom->resjunk)
-                               len++;
-               }
-               else
-                       len += curTle->fjoin->fj_nNodes;
+               if (!curTle->resdom->resjunk)
+                       len++;
        }
        return len;
 }
@@ -2182,10 +2163,8 @@ ExecTargetList(List *targetlist,
 
 #define NPREALLOCDOMAINS 64
        char            nullsArray[NPREALLOCDOMAINS];
-       bool            fjIsNullArray[NPREALLOCDOMAINS];
        ExprDoneCond itemIsDoneArray[NPREALLOCDOMAINS];
        char       *nulls;
-       bool       *fjIsNull;
        ExprDoneCond *itemIsDone;
        List       *tl;
        TargetEntry *tle;
@@ -2223,24 +2202,20 @@ ExecTargetList(List *targetlist,
         * allocate an array of char's to hold the "null" information only if
         * we have a really large targetlist.  otherwise we use the stack.
         *
-        * We also allocate a bool array that is used to hold fjoin result state,
-        * and another array that holds the isDone status for each targetlist
-        * item. The isDone status is needed so that we can iterate,
+        * We also allocate another array that holds the isDone status for each
+        * targetlist item. The isDone status is needed so that we can iterate,
         * generating multiple tuples, when one or more tlist items return
-        * sets.  (We expect the caller to call us again if we return:
-        *
+        * sets.  (We expect the caller to call us again if we return
         * isDone = ExprMultipleResult.)
         */
        if (nodomains > NPREALLOCDOMAINS)
        {
                nulls = (char *) palloc(nodomains * sizeof(char));
-               fjIsNull = (bool *) palloc(nodomains * sizeof(bool));
                itemIsDone = (ExprDoneCond *) palloc(nodomains * sizeof(ExprDoneCond));
        }
        else
        {
                nulls = nullsArray;
-               fjIsNull = fjIsNullArray;
                itemIsDone = itemIsDoneArray;
        }
 
@@ -2257,82 +2232,29 @@ ExecTargetList(List *targetlist,
        {
                tle = lfirst(tl);
 
-               if (tle->resdom != NULL)
-               {
-                       resind = tle->resdom->resno - 1;
+               resind = tle->resdom->resno - 1;
 
-                       values[resind] = ExecEvalExpr(tle->expr,
-                                                                                 econtext,
-                                                                                 &isNull,
-                                                                                 &itemIsDone[resind]);
-                       nulls[resind] = isNull ? 'n' : ' ';
+               values[resind] = ExecEvalExpr((Node *) tle->expr,
+                                                                         econtext,
+                                                                         &isNull,
+                                                                         &itemIsDone[resind]);
+               nulls[resind] = isNull ? 'n' : ' ';
 
-                       if (itemIsDone[resind] != ExprSingleResult)
-                       {
-                               /* We have a set-valued expression in the tlist */
-                               if (isDone == NULL)
-                                       elog(ERROR, "Set-valued function called in context that cannot accept a set");
-                               if (itemIsDone[resind] == ExprMultipleResult)
-                               {
-                                       /* we have undone sets in the tlist, set flag */
-                                       *isDone = ExprMultipleResult;
-                               }
-                               else
-                               {
-                                       /* we have done sets in the tlist, set flag for that */
-                                       haveDoneSets = true;
-                               }
-                       }
-               }
-               else
+               if (itemIsDone[resind] != ExprSingleResult)
                {
-#ifdef SETS_FIXED
-                       int                     curNode;
-                       Resdom     *fjRes;
-                       List       *fjTlist = (List *) tle->expr;
-                       Fjoin      *fjNode = tle->fjoin;
-                       int                     nNodes = fjNode->fj_nNodes;
-                       DatumPtr        results = fjNode->fj_results;
-
-                       ExecEvalFjoin(tle, econtext, fjIsNull, isDone);
-
-                       /*
-                        * XXX this is wrong, but since fjoin code is completely
-                        * broken anyway, I'm not going to worry about it now --- tgl
-                        * 8/23/00
-                        */
-                       if (isDone && *isDone == ExprEndResult)
+                       /* We have a set-valued expression in the tlist */
+                       if (isDone == NULL)
+                               elog(ERROR, "Set-valued function called in context that cannot accept a set");
+                       if (itemIsDone[resind] == ExprMultipleResult)
                        {
-                               MemoryContextSwitchTo(oldContext);
-                               newTuple = NULL;
-                               goto exit;
+                               /* we have undone sets in the tlist, set flag */
+                               *isDone = ExprMultipleResult;
                        }
-
-                       /*
-                        * get the result from the inner node
-                        */
-                       fjRes = (Resdom *) fjNode->fj_innerNode;
-                       resind = fjRes->resno - 1;
-                       values[resind] = results[0];
-                       nulls[resind] = fjIsNull[0] ? 'n' : ' ';
-
-                       /*
-                        * Get results from all of the outer nodes
-                        */
-                       for (curNode = 1;
-                                curNode < nNodes;
-                                curNode++, fjTlist = lnext(fjTlist))
+                       else
                        {
-                               Node       *outernode = lfirst(fjTlist);
-
-                               fjRes = (Resdom *) outernode->iterexpr;
-                               resind = fjRes->resno - 1;
-                               values[resind] = results[curNode];
-                               nulls[resind] = fjIsNull[curNode] ? 'n' : ' ';
+                               /* we have done sets in the tlist, set flag for that */
+                               haveDoneSets = true;
                        }
-#else
-                       elog(ERROR, "ExecTargetList: fjoin nodes not currently supported");
-#endif
                }
        }
 
@@ -2368,7 +2290,7 @@ ExecTargetList(List *targetlist,
 
                                        if (itemIsDone[resind] == ExprEndResult)
                                        {
-                                               values[resind] = ExecEvalExpr(tle->expr,
+                                               values[resind] = ExecEvalExpr((Node *) tle->expr,
                                                                                                          econtext,
                                                                                                          &isNull,
                                                                                                        &itemIsDone[resind]);
@@ -2404,7 +2326,7 @@ ExecTargetList(List *targetlist,
 
                                                while (itemIsDone[resind] == ExprMultipleResult)
                                                {
-                                                       (void) ExecEvalExpr(tle->expr,
+                                                       (void) ExecEvalExpr((Node *) tle->expr,
                                                                                                econtext,
                                                                                                &isNull,
                                                                                                &itemIsDone[resind]);
@@ -2434,7 +2356,6 @@ exit:
        if (nodomains > NPREALLOCDOMAINS)
        {
                pfree(nulls);
-               pfree(fjIsNull);
                pfree(itemIsDone);
        }
 
index f5a6863..eecc108 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.61 2002/12/05 15:50:32 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.62 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -576,93 +576,15 @@ ExecTypeFromTL(List *targetList, bool hasoid)
        foreach(tlitem, targetList)
        {
                TargetEntry *tle = lfirst(tlitem);
-               Resdom     *resdom;
-               Oid                     restype;
-
-               if (tle->resdom != NULL)
-               {
-                       resdom = tle->resdom;
-                       restype = resdom->restype;
-
-                       TupleDescInitEntry(typeInfo,
-                                                          resdom->resno,
-                                                          resdom->resname,
-                                                          restype,
-                                                          resdom->restypmod,
-                                                          0,
-                                                          false);
-
-#ifdef NOT_USED
-                       ExecSetTypeInfo(resdom->resno - 1,
-                                                       typeInfo,
-                                                       (Oid) restype,
-                                                       resdom->resno,
-                                                       resdom->reslen,
-                                                       NameStr(*resdom->resname),
-                                                       get_typbyval(restype),
-                                                       get_typalign(restype));
-#endif
-               }
-               else
-               {
-                       /* XXX this branch looks fairly broken ... tgl 12/2000 */
-                       Resdom     *fjRes;
-                       List       *fjTlistP;
-                       List       *fjList = lfirst(tlitem);
-
-#ifdef SETS_FIXED
-                       TargetEntry *tle;
-                       Fjoin      *fjNode = ((TargetEntry *) lfirst(fjList))->fjoin;
-
-                       tle = fjNode->fj_innerNode; /* ??? */
-#endif
-                       fjRes = tle->resdom;
-                       restype = fjRes->restype;
-
-                       TupleDescInitEntry(typeInfo,
-                                                          fjRes->resno,
-                                                          fjRes->resname,
-                                                          restype,
-                                                          fjRes->restypmod,
-                                                          0,
-                                                          false);
-#ifdef NOT_USED
-                       ExecSetTypeInfo(fjRes->resno - 1,
-                                                       typeInfo,
-                                                       (Oid) restype,
-                                                       fjRes->resno,
-                                                       fjRes->reslen,
-                                                       (char *) fjRes->resname,
-                                                       get_typbyval(restype),
-                                                       get_typalign(restype));
-#endif
-
-                       foreach(fjTlistP, lnext(fjList))
-                       {
-                               TargetEntry *fjTle = lfirst(fjTlistP);
-
-                               fjRes = fjTle->resdom;
-
-                               TupleDescInitEntry(typeInfo,
-                                                                  fjRes->resno,
-                                                                  fjRes->resname,
-                                                                  restype,
-                                                                  fjRes->restypmod,
-                                                                  0,
-                                                                  false);
-
-#ifdef NOT_USED
-                               ExecSetTypeInfo(fjRes->resno - 1,
-                                                               typeInfo,
-                                                               (Oid) fjRes->restype,
-                                                               fjRes->resno,
-                                                               fjRes->reslen,
-                                                               (char *) fjRes->resname,
-                                                               get_typbyval(fjRes->restype),
-                                                               get_typalign(fjRes->restype));
-#endif
-                       }
-               }
+               Resdom     *resdom = tle->resdom;
+
+               TupleDescInitEntry(typeInfo,
+                                                  resdom->resno,
+                                                  resdom->resname,
+                                                  resdom->restype,
+                                                  resdom->restypmod,
+                                                  0,
+                                                  false);
        }
 
        return typeInfo;
index bdbe61c..73e4a80 100644 (file)
@@ -45,7 +45,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.98 2002/12/05 15:50:32 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.99 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -415,7 +415,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
                Datum           newVal;
                bool            isNull;
 
-               newVal = ExecEvalExprSwitchContext(aggref->target, econtext,
+               newVal = ExecEvalExprSwitchContext((Node *) aggref->target, econtext,
                                                                                   &isNull, NULL);
 
                if (aggref->aggdistinct)
@@ -1298,7 +1298,7 @@ ExecInitAgg(Agg *node, EState *estate)
                         * pg_proc.proargtypes, because the latter might be 0.
                         * (Consider COUNT(*).)
                         */
-                       Oid                     inputType = exprType(aggref->target);
+                       Oid                     inputType = exprType((Node *) aggref->target);
 
                        if (!IsBinaryCoercible(inputType, aggform->aggtranstype))
                                elog(ERROR, "Aggregate %u needs to have compatible input type and transition type",
@@ -1312,7 +1312,7 @@ ExecInitAgg(Agg *node, EState *estate)
                         * pg_proc.proargtypes, because the latter might be a pseudotype.
                         * (Consider COUNT(*).)
                         */
-                       Oid                     inputType = exprType(aggref->target);
+                       Oid                     inputType = exprType((Node *) aggref->target);
                        Oid                     eq_function;
 
                        /* We don't implement DISTINCT aggs in the HASHED case */
index e9888c4..0112d36 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.72 2002/12/05 15:50:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.73 2002/12/12 15:49:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -703,28 +703,26 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
                listscan = qual;
                for (j = 0; j < n_keys; j++)
                {
-                       Expr       *clause; /* one clause of index qual */
-                       Oper       *op;         /* operator used in clause */
+                       OpExpr     *clause; /* one clause of index qual */
                        Node       *leftop; /* expr on lhs of operator */
                        Node       *rightop;    /* expr on rhs ... */
                        bits16          flags = 0;
 
                        int                     scanvar;        /* which var identifies varattno */
                        AttrNumber      varattno = 0;   /* att number used in scan */
-                       Oid                     opid;   /* operator id used in scan */
+                       Oid                     opfuncid;               /* operator id used in scan */
                        Datum           scanvalue = 0;  /* value used in scan (if const) */
 
                        /*
                         * extract clause information from the qualification
                         */
-                       clause = lfirst(listscan);
+                       clause = (OpExpr *) lfirst(listscan);
                        listscan = lnext(listscan);
 
-                       op = (Oper *) clause->oper;
-                       if (!IsA(clause, Expr) ||!IsA(op, Oper))
+                       if (!IsA(clause, OpExpr))
                                elog(ERROR, "ExecInitIndexScan: indxqual not an opclause!");
 
-                       opid = op->opid;
+                       opfuncid = clause->opfuncid;
 
                        /*
                         * Here we figure out the contents of the index qual. The
@@ -767,10 +765,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
                        /*
                         * determine information in leftop
                         */
-                       leftop = (Node *) get_leftop(clause);
+                       leftop = (Node *) get_leftop((Expr *) clause);
 
                        if (leftop && IsA(leftop, RelabelType))
-                               leftop = ((RelabelType *) leftop)->arg;
+                               leftop = (Node *) ((RelabelType *) leftop)->arg;
 
                        Assert(leftop != NULL);
 
@@ -834,10 +832,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
                        /*
                         * now determine information in rightop
                         */
-                       rightop = (Node *) get_rightop(clause);
+                       rightop = (Node *) get_rightop((Expr *) clause);
 
                        if (rightop && IsA(rightop, RelabelType))
-                               rightop = ((RelabelType *) rightop)->arg;
+                               rightop = (Node *) ((RelabelType *) rightop)->arg;
 
                        Assert(rightop != NULL);
 
@@ -921,7 +919,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
                                                                   flags,
                                                                   varattno,    /* attribute number to
                                                                                                 * scan */
-                                                                  (RegProcedure) opid, /* reg proc to use */
+                                                                  opfuncid,    /* reg proc to use */
                                                                   scanvalue);  /* constant */
                }
 
index 171738d..e6c2c86 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.52 2002/12/05 15:50:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.53 2002/12/12 15:49:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -119,16 +119,14 @@ MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals)
        ltcdr = *ltQuals;
        foreach(gtcdr, *gtQuals)
        {
-               Expr       *ltqual = (Expr *) lfirst(ltcdr);
-               Expr       *gtqual = (Expr *) lfirst(gtcdr);
-               Oper       *ltop = (Oper *) ltqual->oper;
-               Oper       *gtop = (Oper *) gtqual->oper;
+               OpExpr     *ltop = (OpExpr *) lfirst(ltcdr);
+               OpExpr     *gtop = (OpExpr *) lfirst(gtcdr);
 
                /*
                 * The two ops should be identical, so use either one for lookup.
                 */
-               if (!IsA(ltop, Oper))
-                       elog(ERROR, "MJFormSkipQuals: op not an Oper!");
+               if (!IsA(ltop, OpExpr))
+                       elog(ERROR, "MJFormSkipQuals: op not an OpExpr!");
 
                /*
                 * Lookup the operators, and replace the data in the copied
@@ -137,8 +135,8 @@ MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals)
                op_mergejoin_crossops(ltop->opno,
                                                          &ltop->opno,
                                                          &gtop->opno,
-                                                         &ltop->opid,
-                                                         &gtop->opid);
+                                                         &ltop->opfuncid,
+                                                         &gtop->opfuncid);
                ltop->op_fcache = NULL;
                gtop->op_fcache = NULL;
 
index 195634c..880a623 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.35 2002/12/05 15:50:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.36 2002/12/12 15:49:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
                        ExprContext *econtext, bool *isNull)
 {
        PlanState  *planstate = node->planstate;
-       SubPlan    *subplan = (SubPlan *) node->ps.plan;
+       SubPlanExpr *subplan = (SubPlanExpr *) node->ps.plan;
        SubLink    *sublink = subplan->sublink;
        SubLinkType subLinkType = sublink->subLinkType;
        bool            useor = sublink->useor;
@@ -151,7 +151,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
                 */
                foreach(lst, sublink->oper)
                {
-                       Expr       *expr = (Expr *) lfirst(lst);
+                       OpExpr     *expr = (OpExpr *) lfirst(lst);
                        Param      *prm = lsecond(expr->args);
                        ParamExecData *prmdata;
                        Datum           expresult;
@@ -172,8 +172,8 @@ ExecSubPlan(SubPlanState *node, List *pvar,
                        {
                                switch (nodeTag(prm))
                                {
-                                       case T_Expr:
-                                               prm = lfirst(((Expr *) prm)->args);
+                                       case T_FuncExpr:
+                                               prm = lfirst(((FuncExpr *) prm)->args);
                                                break;
                                        case T_RelabelType:
                                                prm = (Param *) (((RelabelType *) prm)->arg);
@@ -288,7 +288,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
  * ----------------------------------------------------------------
  */
 SubPlanState *
-ExecInitSubPlan(SubPlan *node, EState *estate)
+ExecInitSubPlan(SubPlanExpr *node, EState *estate)
 {
        SubPlanState *subplanstate;
        EState     *sp_estate;
@@ -374,7 +374,7 @@ void
 ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 {
        PlanState  *planstate = node->planstate;
-       SubPlan    *subplan = (SubPlan *) node->ps.plan;
+       SubPlanExpr *subplan = (SubPlanExpr *) node->ps.plan;
        SubLink    *sublink = subplan->sublink;
        EState     *estate = node->ps.state;
        MemoryContext oldcontext;
@@ -497,7 +497,7 @@ void
 ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
 {
        PlanState  *planstate = node->planstate;
-       SubPlan    *subplan = (SubPlan *) node->ps.plan;
+       SubPlanExpr *subplan = (SubPlanExpr *) node->ps.plan;
        EState     *estate = node->ps.state;
        List       *lst;
 
index a978e23..f7aa8fc 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.229 2002/12/06 05:00:18 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.230 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -563,21 +563,6 @@ _copyLimit(Limit *from)
        return newnode;
 }
 
-static SubPlan *
-_copySubPlan(SubPlan *from)
-{
-       SubPlan    *newnode = makeNode(SubPlan);
-
-       COPY_NODE_FIELD(plan);
-       COPY_SCALAR_FIELD(plan_id);
-       COPY_NODE_FIELD(rtable);
-       COPY_INTLIST_FIELD(setParam);
-       COPY_INTLIST_FIELD(parParam);
-       COPY_NODE_FIELD(sublink);
-
-       return newnode;
-}
-
 /* ****************************************************************
  *                                        primnodes.h copy functions
  * ****************************************************************
@@ -603,20 +588,9 @@ _copyResdom(Resdom *from)
        return newnode;
 }
 
-static Fjoin *
-_copyFjoin(Fjoin *from)
-{
-       Fjoin      *newnode = makeNode(Fjoin);
-
-       COPY_SCALAR_FIELD(fj_initialized);
-       COPY_SCALAR_FIELD(fj_nNodes);
-       COPY_NODE_FIELD(fj_innerNode);
-       COPY_POINTER_FIELD(fj_results, from->fj_nNodes * sizeof(Datum));
-       COPY_POINTER_FIELD(fj_alwaysDone, from->fj_nNodes * sizeof(bool));
-
-       return newnode;
-}
-
+/*
+ * _copyAlias
+ */
 static Alias *
 _copyAlias(Alias *from)
 {
@@ -628,6 +602,9 @@ _copyAlias(Alias *from)
        return newnode;
 }
 
+/*
+ * _copyRangeVar
+ */
 static RangeVar *
 _copyRangeVar(RangeVar *from)
 {
@@ -644,20 +621,11 @@ _copyRangeVar(RangeVar *from)
 }
 
 /*
- * _copyExpr
+ * We don't need a _copyExpr because Expr is an abstract supertype which
+ * should never actually get instantiated.  Also, since it has no common
+ * fields except NodeTag, there's no need for a helper routine to factor
+ * out copying the common fields...
  */
-static Expr *
-_copyExpr(Expr *from)
-{
-       Expr       *newnode = makeNode(Expr);
-
-       COPY_SCALAR_FIELD(typeOid);
-       COPY_SCALAR_FIELD(opType);
-       COPY_NODE_FIELD(oper);
-       COPY_NODE_FIELD(args);
-
-       return newnode;
-}
 
 /*
  * _copyVar
@@ -679,25 +647,6 @@ _copyVar(Var *from)
 }
 
 /*
- * _copyOper
- */
-static Oper *
-_copyOper(Oper *from)
-{
-       Oper       *newnode = makeNode(Oper);
-
-       COPY_SCALAR_FIELD(opno);
-       COPY_SCALAR_FIELD(opid);
-       COPY_SCALAR_FIELD(opresulttype);
-       COPY_SCALAR_FIELD(opretset);
-
-       /* Do not copy the run-time state, if any */
-       newnode->op_fcache = NULL;
-
-       return newnode;
-}
-
-/*
  * _copyConst
  */
 static Const *
@@ -749,17 +698,57 @@ _copyParam(Param *from)
 }
 
 /*
- * _copyFunc
+ * _copyAggref
  */
-static Func *
-_copyFunc(Func *from)
+static Aggref *
+_copyAggref(Aggref *from)
 {
-       Func       *newnode = makeNode(Func);
+       Aggref     *newnode = makeNode(Aggref);
+
+       COPY_SCALAR_FIELD(aggfnoid);
+       COPY_SCALAR_FIELD(aggtype);
+       COPY_NODE_FIELD(target);
+       COPY_SCALAR_FIELD(aggstar);
+       COPY_SCALAR_FIELD(aggdistinct);
+       COPY_SCALAR_FIELD(aggno);       /* will go away soon */
+
+       return newnode;
+}
+
+/*
+ * _copyArrayRef
+ */
+static ArrayRef *
+_copyArrayRef(ArrayRef *from)
+{
+       ArrayRef   *newnode = makeNode(ArrayRef);
+
+       COPY_SCALAR_FIELD(refrestype);
+       COPY_SCALAR_FIELD(refattrlength);
+       COPY_SCALAR_FIELD(refelemlength);
+       COPY_SCALAR_FIELD(refelembyval);
+       COPY_SCALAR_FIELD(refelemalign);
+       COPY_NODE_FIELD(refupperindexpr);
+       COPY_NODE_FIELD(reflowerindexpr);
+       COPY_NODE_FIELD(refexpr);
+       COPY_NODE_FIELD(refassgnexpr);
+
+       return newnode;
+}
+
+/*
+ * _copyFuncExpr
+ */
+static FuncExpr *
+_copyFuncExpr(FuncExpr *from)
+{
+       FuncExpr           *newnode = makeNode(FuncExpr);
 
        COPY_SCALAR_FIELD(funcid);
        COPY_SCALAR_FIELD(funcresulttype);
        COPY_SCALAR_FIELD(funcretset);
        COPY_SCALAR_FIELD(funcformat);
+       COPY_NODE_FIELD(args);
 
        /* Do not copy the run-time state, if any */
        newnode->func_fcache = NULL;
@@ -768,19 +757,55 @@ _copyFunc(Func *from)
 }
 
 /*
- * _copyAggref
+ * _copyOpExpr
  */
-static Aggref *
-_copyAggref(Aggref *from)
+static OpExpr *
+_copyOpExpr(OpExpr *from)
 {
-       Aggref     *newnode = makeNode(Aggref);
+       OpExpr     *newnode = makeNode(OpExpr);
 
-       COPY_SCALAR_FIELD(aggfnoid);
-       COPY_SCALAR_FIELD(aggtype);
-       COPY_NODE_FIELD(target);
-       COPY_SCALAR_FIELD(aggstar);
-       COPY_SCALAR_FIELD(aggdistinct);
-       COPY_SCALAR_FIELD(aggno);       /* probably not necessary */
+       COPY_SCALAR_FIELD(opno);
+       COPY_SCALAR_FIELD(opfuncid);
+       COPY_SCALAR_FIELD(opresulttype);
+       COPY_SCALAR_FIELD(opretset);
+       COPY_NODE_FIELD(args);
+
+       /* Do not copy the run-time state, if any */
+       newnode->op_fcache = NULL;
+
+       return newnode;
+}
+
+/*
+ * _copyDistinctExpr
+ */
+static DistinctExpr *
+_copyDistinctExpr(DistinctExpr *from)
+{
+       DistinctExpr       *newnode = makeNode(DistinctExpr);
+
+       COPY_SCALAR_FIELD(opno);
+       COPY_SCALAR_FIELD(opfuncid);
+       COPY_SCALAR_FIELD(opresulttype);
+       COPY_SCALAR_FIELD(opretset);
+       COPY_NODE_FIELD(args);
+
+       /* Do not copy the run-time state, if any */
+       newnode->op_fcache = NULL;
+
+       return newnode;
+}
+
+/*
+ * _copyBoolExpr
+ */
+static BoolExpr *
+_copyBoolExpr(BoolExpr *from)
+{
+       BoolExpr           *newnode = makeNode(BoolExpr);
+
+       COPY_SCALAR_FIELD(boolop);
+       COPY_NODE_FIELD(args);
 
        return newnode;
 }
@@ -803,6 +828,26 @@ _copySubLink(SubLink *from)
 }
 
 /*
+ * _copySubPlanExpr
+ */
+static SubPlanExpr *
+_copySubPlanExpr(SubPlanExpr *from)
+{
+       SubPlanExpr    *newnode = makeNode(SubPlanExpr);
+
+       COPY_SCALAR_FIELD(typeOid);
+       COPY_NODE_FIELD(plan);
+       COPY_SCALAR_FIELD(plan_id);
+       COPY_NODE_FIELD(rtable);
+       COPY_INTLIST_FIELD(setParam);
+       COPY_INTLIST_FIELD(parParam);
+       COPY_NODE_FIELD(args);
+       COPY_NODE_FIELD(sublink);
+
+       return newnode;
+}
+
+/*
  * _copyFieldSelect
  */
 static FieldSelect *
@@ -834,6 +879,112 @@ _copyRelabelType(RelabelType *from)
        return newnode;
 }
 
+/*
+ * _copyCaseExpr
+ */
+static CaseExpr *
+_copyCaseExpr(CaseExpr *from)
+{
+       CaseExpr   *newnode = makeNode(CaseExpr);
+
+       COPY_SCALAR_FIELD(casetype);
+       COPY_NODE_FIELD(arg);
+       COPY_NODE_FIELD(args);
+       COPY_NODE_FIELD(defresult);
+
+       return newnode;
+}
+
+/*
+ * _copyCaseWhen
+ */
+static CaseWhen *
+_copyCaseWhen(CaseWhen *from)
+{
+       CaseWhen   *newnode = makeNode(CaseWhen);
+
+       COPY_NODE_FIELD(expr);
+       COPY_NODE_FIELD(result);
+
+       return newnode;
+}
+
+/*
+ * _copyNullTest
+ */
+static NullTest *
+_copyNullTest(NullTest *from)
+{
+       NullTest   *newnode = makeNode(NullTest);
+
+       COPY_NODE_FIELD(arg);
+       COPY_SCALAR_FIELD(nulltesttype);
+
+       return newnode;
+}
+
+/*
+ * _copyBooleanTest
+ */
+static BooleanTest *
+_copyBooleanTest(BooleanTest *from)
+{
+       BooleanTest *newnode = makeNode(BooleanTest);
+
+       COPY_NODE_FIELD(arg);
+       COPY_SCALAR_FIELD(booltesttype);
+
+       return newnode;
+}
+
+/*
+ * _copyConstraintTest
+ */
+static ConstraintTest *
+_copyConstraintTest(ConstraintTest *from)
+{
+       ConstraintTest *newnode = makeNode(ConstraintTest);
+
+       COPY_NODE_FIELD(arg);
+       COPY_SCALAR_FIELD(testtype);
+       COPY_STRING_FIELD(name);
+       COPY_STRING_FIELD(domname);
+       COPY_NODE_FIELD(check_expr);
+
+       return newnode;
+}
+
+/*
+ * _copyConstraintTestValue
+ */
+static ConstraintTestValue *
+_copyConstraintTestValue(ConstraintTestValue *from)
+{
+       ConstraintTestValue *newnode = makeNode(ConstraintTestValue);
+
+       COPY_SCALAR_FIELD(typeId);
+       COPY_SCALAR_FIELD(typeMod);
+
+       return newnode;
+}
+
+/*
+ * _copyTargetEntry
+ */
+static TargetEntry *
+_copyTargetEntry(TargetEntry *from)
+{
+       TargetEntry *newnode = makeNode(TargetEntry);
+
+       COPY_NODE_FIELD(resdom);
+       COPY_NODE_FIELD(expr);
+
+       return newnode;
+}
+
+/*
+ * _copyRangeTblRef
+ */
 static RangeTblRef *
 _copyRangeTblRef(RangeTblRef *from)
 {
@@ -844,6 +995,9 @@ _copyRangeTblRef(RangeTblRef *from)
        return newnode;
 }
 
+/*
+ * _copyJoinExpr
+ */
 static JoinExpr *
 _copyJoinExpr(JoinExpr *from)
 {
@@ -861,6 +1015,9 @@ _copyJoinExpr(JoinExpr *from)
        return newnode;
 }
 
+/*
+ * _copyFromExpr
+ */
 static FromExpr *
 _copyFromExpr(FromExpr *from)
 {
@@ -872,24 +1029,6 @@ _copyFromExpr(FromExpr *from)
        return newnode;
 }
 
-static ArrayRef *
-_copyArrayRef(ArrayRef *from)
-{
-       ArrayRef   *newnode = makeNode(ArrayRef);
-
-       COPY_SCALAR_FIELD(refrestype);
-       COPY_SCALAR_FIELD(refattrlength);
-       COPY_SCALAR_FIELD(refelemlength);
-       COPY_SCALAR_FIELD(refelembyval);
-       COPY_SCALAR_FIELD(refelemalign);
-       COPY_NODE_FIELD(refupperindexpr);
-       COPY_NODE_FIELD(reflowerindexpr);
-       COPY_NODE_FIELD(refexpr);
-       COPY_NODE_FIELD(refassgnexpr);
-
-       return newnode;
-}
-
 /* ****************************************************************
  *                                             relation.h copy functions
  *
@@ -964,18 +1103,6 @@ _copyJoinInfo(JoinInfo *from)
  * ****************************************************************
  */
 
-static TargetEntry *
-_copyTargetEntry(TargetEntry *from)
-{
-       TargetEntry *newnode = makeNode(TargetEntry);
-
-       COPY_NODE_FIELD(resdom);
-       COPY_NODE_FIELD(fjoin);
-       COPY_NODE_FIELD(expr);
-
-       return newnode;
-}
-
 static RangeTblEntry *
 _copyRangeTblEntry(RangeTblEntry *from)
 {
@@ -1170,6 +1297,14 @@ _copyTypeName(TypeName *from)
        return newnode;
 }
 
+static DomainConstraintValue *
+_copyDomainConstraintValue(DomainConstraintValue *from)
+{
+       DomainConstraintValue *newnode = makeNode(DomainConstraintValue);
+
+       return newnode;
+}
+
 static SortGroupBy *
 _copySortGroupBy(SortGroupBy *from)
 {
@@ -1260,85 +1395,6 @@ _copyConstraint(Constraint *from)
        return newnode;
 }
 
-static CaseExpr *
-_copyCaseExpr(CaseExpr *from)
-{
-       CaseExpr   *newnode = makeNode(CaseExpr);
-
-       COPY_SCALAR_FIELD(casetype);
-       COPY_NODE_FIELD(arg);
-       COPY_NODE_FIELD(args);
-       COPY_NODE_FIELD(defresult);
-
-       return newnode;
-}
-
-static CaseWhen *
-_copyCaseWhen(CaseWhen *from)
-{
-       CaseWhen   *newnode = makeNode(CaseWhen);
-
-       COPY_NODE_FIELD(expr);
-       COPY_NODE_FIELD(result);
-
-       return newnode;
-}
-
-static NullTest *
-_copyNullTest(NullTest *from)
-{
-       NullTest   *newnode = makeNode(NullTest);
-
-       COPY_NODE_FIELD(arg);
-       COPY_SCALAR_FIELD(nulltesttype);
-
-       return newnode;
-}
-
-static BooleanTest *
-_copyBooleanTest(BooleanTest *from)
-{
-       BooleanTest *newnode = makeNode(BooleanTest);
-
-       COPY_NODE_FIELD(arg);
-       COPY_SCALAR_FIELD(booltesttype);
-
-       return newnode;
-}
-
-static ConstraintTest *
-_copyConstraintTest(ConstraintTest *from)
-{
-       ConstraintTest *newnode = makeNode(ConstraintTest);
-
-       COPY_NODE_FIELD(arg);
-       COPY_SCALAR_FIELD(testtype);
-       COPY_STRING_FIELD(name);
-       COPY_STRING_FIELD(domname);
-       COPY_NODE_FIELD(check_expr);
-
-       return newnode;
-}
-
-static DomainConstraintValue *
-_copyDomainConstraintValue(DomainConstraintValue *from)
-{
-       DomainConstraintValue *newnode = makeNode(DomainConstraintValue);
-
-       return newnode;
-}
-
-static ConstraintTestValue *
-_copyConstraintTestValue(ConstraintTestValue *from)
-{
-       ConstraintTestValue *newnode = makeNode(ConstraintTestValue);
-
-       COPY_SCALAR_FIELD(typeId);
-       COPY_SCALAR_FIELD(typeMod);
-
-       return newnode;
-}
-
 static DefElem *
 _copyDefElem(DefElem *from)
 {
@@ -2350,9 +2406,6 @@ copyObject(void *from)
                case T_Limit:
                        retval = _copyLimit(from);
                        break;
-               case T_SubPlan:
-                       retval = _copySubPlan(from);
-                       break;
 
                        /*
                         * PRIMITIVE NODES
@@ -2360,45 +2413,72 @@ copyObject(void *from)
                case T_Resdom:
                        retval = _copyResdom(from);
                        break;
-               case T_Fjoin:
-                       retval = _copyFjoin(from);
-                       break;
                case T_Alias:
                        retval = _copyAlias(from);
                        break;
                case T_RangeVar:
                        retval = _copyRangeVar(from);
                        break;
-               case T_Expr:
-                       retval = _copyExpr(from);
-                       break;
                case T_Var:
                        retval = _copyVar(from);
                        break;
-               case T_Oper:
-                       retval = _copyOper(from);
-                       break;
                case T_Const:
                        retval = _copyConst(from);
                        break;
                case T_Param:
                        retval = _copyParam(from);
                        break;
-               case T_Func:
-                       retval = _copyFunc(from);
-                       break;
                case T_Aggref:
                        retval = _copyAggref(from);
                        break;
+               case T_ArrayRef:
+                       retval = _copyArrayRef(from);
+                       break;
+               case T_FuncExpr:
+                       retval = _copyFuncExpr(from);
+                       break;
+               case T_OpExpr:
+                       retval = _copyOpExpr(from);
+                       break;
+               case T_DistinctExpr:
+                       retval = _copyDistinctExpr(from);
+                       break;
+               case T_BoolExpr:
+                       retval = _copyBoolExpr(from);
+                       break;
                case T_SubLink:
                        retval = _copySubLink(from);
                        break;
+               case T_SubPlanExpr:
+                       retval = _copySubPlanExpr(from);
+                       break;
                case T_FieldSelect:
                        retval = _copyFieldSelect(from);
                        break;
                case T_RelabelType:
                        retval = _copyRelabelType(from);
                        break;
+               case T_CaseExpr:
+                       retval = _copyCaseExpr(from);
+                       break;
+               case T_CaseWhen:
+                       retval = _copyCaseWhen(from);
+                       break;
+               case T_NullTest:
+                       retval = _copyNullTest(from);
+                       break;
+               case T_BooleanTest:
+                       retval = _copyBooleanTest(from);
+                       break;
+               case T_ConstraintTest:
+                       retval = _copyConstraintTest(from);
+                       break;
+               case T_ConstraintTestValue:
+                       retval = _copyConstraintTestValue(from);
+                       break;
+               case T_TargetEntry:
+                       retval = _copyTargetEntry(from);
+                       break;
                case T_RangeTblRef:
                        retval = _copyRangeTblRef(from);
                        break;
@@ -2408,9 +2488,6 @@ copyObject(void *from)
                case T_FromExpr:
                        retval = _copyFromExpr(from);
                        break;
-               case T_ArrayRef:
-                       retval = _copyArrayRef(from);
-                       break;
 
                        /*
                         * RELATION NODES
@@ -2686,6 +2763,9 @@ copyObject(void *from)
                case T_TypeCast:
                        retval = _copyTypeCast(from);
                        break;
+               case T_DomainConstraintValue:
+                       retval = _copyDomainConstraintValue(from);
+                       break;
                case T_SortGroupBy:
                        retval = _copySortGroupBy(from);
                        break;
@@ -2710,9 +2790,6 @@ copyObject(void *from)
                case T_DefElem:
                        retval = _copyDefElem(from);
                        break;
-               case T_TargetEntry:
-                       retval = _copyTargetEntry(from);
-                       break;
                case T_RangeTblEntry:
                        retval = _copyRangeTblEntry(from);
                        break;
@@ -2722,24 +2799,6 @@ copyObject(void *from)
                case T_GroupClause:
                        retval = _copyGroupClause(from);
                        break;
-               case T_CaseExpr:
-                       retval = _copyCaseExpr(from);
-                       break;
-               case T_CaseWhen:
-                       retval = _copyCaseWhen(from);
-                       break;
-               case T_NullTest:
-                       retval = _copyNullTest(from);
-                       break;
-               case T_BooleanTest:
-                       retval = _copyBooleanTest(from);
-                       break;
-               case T_ConstraintTest:
-                       retval = _copyConstraintTest(from);
-                       break;
-               case T_ConstraintTestValue:
-                       retval = _copyConstraintTestValue(from);
-                       break;
                case T_FkConstraint:
                        retval = _copyFkConstraint(from);
                        break;
@@ -2752,9 +2811,6 @@ copyObject(void *from)
                case T_InsertDefault:
                        retval = _copyInsertDefault(from);
                        break;
-               case T_DomainConstraintValue:
-                       retval = _copyDomainConstraintValue(from);
-                       break;
 
                default:
                        elog(ERROR, "copyObject: don't know how to copy node type %d",
index 7122709..3b51038 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.174 2002/12/06 05:00:18 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.175 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,7 +27,6 @@
 
 #include "nodes/params.h"
 #include "nodes/parsenodes.h"
-#include "nodes/plannodes.h"
 #include "nodes/relation.h"
 #include "utils/datum.h"
 
@@ -99,18 +98,6 @@ _equalResdom(Resdom *a, Resdom *b)
 }
 
 static bool
-_equalFjoin(Fjoin *a, Fjoin *b)
-{
-       COMPARE_SCALAR_FIELD(fj_initialized);
-       COMPARE_SCALAR_FIELD(fj_nNodes);
-       COMPARE_NODE_FIELD(fj_innerNode);
-       COMPARE_POINTER_FIELD(fj_results, a->fj_nNodes * sizeof(Datum));
-       COMPARE_POINTER_FIELD(fj_alwaysDone, a->fj_nNodes * sizeof(bool));
-
-       return true;
-}
-
-static bool
 _equalAlias(Alias *a, Alias *b)
 {
        COMPARE_STRING_FIELD(aliasname);
@@ -132,20 +119,12 @@ _equalRangeVar(RangeVar *a, RangeVar *b)
        return true;
 }
 
-static bool
-_equalExpr(Expr *a, Expr *b)
-{
-       /*
-        * We do not examine typeOid, since the optimizer often doesn't bother
-        * to set it in created nodes, and it is logically a derivative of the
-        * oper field anyway.
-        */
-       COMPARE_SCALAR_FIELD(opType);
-       COMPARE_NODE_FIELD(oper);
-       COMPARE_NODE_FIELD(args);
-
-       return true;
-}
+/*
+ * We don't need an _equalExpr because Expr is an abstract supertype which
+ * should never actually get instantiated.  Also, since it has no common
+ * fields except NodeTag, there's no need for a helper routine to factor
+ * out comparing the common fields...
+ */
 
 static bool
 _equalVar(Var *a, Var *b)
@@ -162,28 +141,6 @@ _equalVar(Var *a, Var *b)
 }
 
 static bool
-_equalOper(Oper *a, Oper *b)
-{
-       COMPARE_SCALAR_FIELD(opno);
-       COMPARE_SCALAR_FIELD(opresulttype);
-       COMPARE_SCALAR_FIELD(opretset);
-
-       /*
-        * We do not examine opid or op_fcache, since these are logically
-        * derived from opno, and they may not be set yet depending on how far
-        * along the node is in the parse/plan pipeline.
-        *
-        * (Besides, op_fcache is executor state, which we don't check --- see
-        * notes at head of file.)
-        *
-        * It's probably not really necessary to check opresulttype or opretset,
-        * either...
-        */
-
-       return true;
-}
-
-static bool
 _equalConst(Const *a, Const *b)
 {
        COMPARE_SCALAR_FIELD(consttype);
@@ -226,7 +183,35 @@ _equalParam(Param *a, Param *b)
 }
 
 static bool
-_equalFunc(Func *a, Func *b)
+_equalAggref(Aggref *a, Aggref *b)
+{
+       COMPARE_SCALAR_FIELD(aggfnoid);
+       COMPARE_SCALAR_FIELD(aggtype);
+       COMPARE_NODE_FIELD(target);
+       COMPARE_SCALAR_FIELD(aggstar);
+       COMPARE_SCALAR_FIELD(aggdistinct);
+
+       return true;
+}
+
+static bool
+_equalArrayRef(ArrayRef *a, ArrayRef *b)
+{
+       COMPARE_SCALAR_FIELD(refrestype);
+       COMPARE_SCALAR_FIELD(refattrlength);
+       COMPARE_SCALAR_FIELD(refelemlength);
+       COMPARE_SCALAR_FIELD(refelembyval);
+       COMPARE_SCALAR_FIELD(refelemalign);
+       COMPARE_NODE_FIELD(refupperindexpr);
+       COMPARE_NODE_FIELD(reflowerindexpr);
+       COMPARE_NODE_FIELD(refexpr);
+       COMPARE_NODE_FIELD(refassgnexpr);
+
+       return true;
+}
+
+static bool
+_equalFuncExpr(FuncExpr *a, FuncExpr *b)
 {
        COMPARE_SCALAR_FIELD(funcid);
        COMPARE_SCALAR_FIELD(funcresulttype);
@@ -240,20 +225,60 @@ _equalFunc(Func *a, Func *b)
                b->funcformat != COERCE_DONTCARE)
                return false;
 
-       /* Note we do not look at func_fcache; see notes for _equalOper */
+       COMPARE_NODE_FIELD(args);
 
        return true;
 }
 
 static bool
-_equalAggref(Aggref *a, Aggref *b)
+_equalOpExpr(OpExpr *a, OpExpr *b)
 {
-       COMPARE_SCALAR_FIELD(aggfnoid);
-       COMPARE_SCALAR_FIELD(aggtype);
-       COMPARE_NODE_FIELD(target);
-       COMPARE_SCALAR_FIELD(aggstar);
-       COMPARE_SCALAR_FIELD(aggdistinct);
-       /* ignore aggno, which is only a private field for the executor */
+       COMPARE_SCALAR_FIELD(opno);
+       /*
+        * Special-case opfuncid: it is allowable for it to differ if one
+        * node contains zero and the other doesn't.  This just means that the
+        * one node isn't as far along in the parse/plan pipeline and hasn't
+        * had the opfuncid cache filled yet.
+        */
+       if (a->opfuncid != b->opfuncid &&
+               a->opfuncid != 0 &&
+               b->opfuncid != 0)
+               return false;
+
+       COMPARE_SCALAR_FIELD(opresulttype);
+       COMPARE_SCALAR_FIELD(opretset);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
+static bool
+_equalDistinctExpr(DistinctExpr *a, DistinctExpr *b)
+{
+       COMPARE_SCALAR_FIELD(opno);
+       /*
+        * Special-case opfuncid: it is allowable for it to differ if one
+        * node contains zero and the other doesn't.  This just means that the
+        * one node isn't as far along in the parse/plan pipeline and hasn't
+        * had the opfuncid cache filled yet.
+        */
+       if (a->opfuncid != b->opfuncid &&
+               a->opfuncid != 0 &&
+               b->opfuncid != 0)
+               return false;
+
+       COMPARE_SCALAR_FIELD(opresulttype);
+       COMPARE_SCALAR_FIELD(opretset);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
+static bool
+_equalBoolExpr(BoolExpr *a, BoolExpr *b)
+{
+       COMPARE_SCALAR_FIELD(boolop);
+       COMPARE_NODE_FIELD(args);
 
        return true;
 }
@@ -271,6 +296,21 @@ _equalSubLink(SubLink *a, SubLink *b)
 }
 
 static bool
+_equalSubPlanExpr(SubPlanExpr *a, SubPlanExpr *b)
+{
+       COMPARE_SCALAR_FIELD(typeOid);
+       /* should compare plans, but have to settle for comparing plan IDs */
+       COMPARE_SCALAR_FIELD(plan_id);
+       COMPARE_NODE_FIELD(rtable);
+       COMPARE_INTLIST_FIELD(setParam);
+       COMPARE_INTLIST_FIELD(parParam);
+       COMPARE_NODE_FIELD(args);
+       COMPARE_NODE_FIELD(sublink);
+
+       return true;
+}
+
+static bool
 _equalFieldSelect(FieldSelect *a, FieldSelect *b)
 {
        COMPARE_NODE_FIELD(arg);
@@ -300,66 +340,101 @@ _equalRelabelType(RelabelType *a, RelabelType *b)
 }
 
 static bool
-_equalRangeTblRef(RangeTblRef *a, RangeTblRef *b)
+_equalCaseExpr(CaseExpr *a, CaseExpr *b)
 {
-       COMPARE_SCALAR_FIELD(rtindex);
+       COMPARE_SCALAR_FIELD(casetype);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_NODE_FIELD(args);
+       COMPARE_NODE_FIELD(defresult);
 
        return true;
 }
 
 static bool
-_equalJoinExpr(JoinExpr *a, JoinExpr *b)
+_equalCaseWhen(CaseWhen *a, CaseWhen *b)
 {
-       COMPARE_SCALAR_FIELD(jointype);
-       COMPARE_SCALAR_FIELD(isNatural);
-       COMPARE_NODE_FIELD(larg);
-       COMPARE_NODE_FIELD(rarg);
-       COMPARE_NODE_FIELD(using);
-       COMPARE_NODE_FIELD(quals);
-       COMPARE_NODE_FIELD(alias);
-       COMPARE_SCALAR_FIELD(rtindex);
+       COMPARE_NODE_FIELD(expr);
+       COMPARE_NODE_FIELD(result);
 
        return true;
 }
 
 static bool
-_equalFromExpr(FromExpr *a, FromExpr *b)
+_equalNullTest(NullTest *a, NullTest *b)
 {
-       COMPARE_NODE_FIELD(fromlist);
-       COMPARE_NODE_FIELD(quals);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_SCALAR_FIELD(nulltesttype);
 
        return true;
 }
 
 static bool
-_equalArrayRef(ArrayRef *a, ArrayRef *b)
+_equalBooleanTest(BooleanTest *a, BooleanTest *b)
 {
-       COMPARE_SCALAR_FIELD(refrestype);
-       COMPARE_SCALAR_FIELD(refattrlength);
-       COMPARE_SCALAR_FIELD(refelemlength);
-       COMPARE_SCALAR_FIELD(refelembyval);
-       COMPARE_SCALAR_FIELD(refelemalign);
-       COMPARE_NODE_FIELD(refupperindexpr);
-       COMPARE_NODE_FIELD(reflowerindexpr);
-       COMPARE_NODE_FIELD(refexpr);
-       COMPARE_NODE_FIELD(refassgnexpr);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_SCALAR_FIELD(booltesttype);
 
        return true;
 }
 
+static bool
+_equalConstraintTest(ConstraintTest *a, ConstraintTest *b)
+{
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_SCALAR_FIELD(testtype);
+       COMPARE_STRING_FIELD(name);
+       COMPARE_STRING_FIELD(domname);
+       COMPARE_NODE_FIELD(check_expr);
 
-/*
- * Stuff from plannodes.h
- */
+       return true;
+}
 
 static bool
-_equalSubPlan(SubPlan *a, SubPlan *b)
+_equalConstraintTestValue(ConstraintTestValue *a, ConstraintTestValue *b)
 {
-       /* should compare plans, but have to settle for comparing plan IDs */
-       COMPARE_SCALAR_FIELD(plan_id);
+       COMPARE_SCALAR_FIELD(typeId);
+       COMPARE_SCALAR_FIELD(typeMod);
 
-       COMPARE_NODE_FIELD(rtable);
-       COMPARE_NODE_FIELD(sublink);
+       return true;
+}
+
+static bool
+_equalTargetEntry(TargetEntry *a, TargetEntry *b)
+{
+       COMPARE_NODE_FIELD(resdom);
+       COMPARE_NODE_FIELD(expr);
+
+       return true;
+}
+
+static bool
+_equalRangeTblRef(RangeTblRef *a, RangeTblRef *b)
+{
+       COMPARE_SCALAR_FIELD(rtindex);
+
+       return true;
+}
+
+static bool
+_equalJoinExpr(JoinExpr *a, JoinExpr *b)
+{
+       COMPARE_SCALAR_FIELD(jointype);
+       COMPARE_SCALAR_FIELD(isNatural);
+       COMPARE_NODE_FIELD(larg);
+       COMPARE_NODE_FIELD(rarg);
+       COMPARE_NODE_FIELD(using);
+       COMPARE_NODE_FIELD(quals);
+       COMPARE_NODE_FIELD(alias);
+       COMPARE_SCALAR_FIELD(rtindex);
+
+       return true;
+}
+
+static bool
+_equalFromExpr(FromExpr *a, FromExpr *b)
+{
+       COMPARE_NODE_FIELD(fromlist);
+       COMPARE_NODE_FIELD(quals);
 
        return true;
 }
@@ -574,6 +649,12 @@ _equalInsertDefault(InsertDefault *a, InsertDefault *b)
 }
 
 static bool
+_equalDomainConstraintValue(DomainConstraintValue *a, DomainConstraintValue *b)
+{
+       return true;
+}
+
+static bool
 _equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
 {
        COMPARE_STRING_FIELD(portalname);
@@ -1341,16 +1422,6 @@ _equalDefElem(DefElem *a, DefElem *b)
 }
 
 static bool
-_equalTargetEntry(TargetEntry *a, TargetEntry *b)
-{
-       COMPARE_NODE_FIELD(resdom);
-       COMPARE_NODE_FIELD(fjoin);
-       COMPARE_NODE_FIELD(expr);
-
-       return true;
-}
-
-static bool
 _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
 {
        COMPARE_SCALAR_FIELD(rtekind);
@@ -1397,71 +1468,6 @@ _equalFkConstraint(FkConstraint *a, FkConstraint *b)
        return true;
 }
 
-static bool
-_equalCaseExpr(CaseExpr *a, CaseExpr *b)
-{
-       COMPARE_SCALAR_FIELD(casetype);
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_NODE_FIELD(args);
-       COMPARE_NODE_FIELD(defresult);
-
-       return true;
-}
-
-static bool
-_equalCaseWhen(CaseWhen *a, CaseWhen *b)
-{
-       COMPARE_NODE_FIELD(expr);
-       COMPARE_NODE_FIELD(result);
-
-       return true;
-}
-
-static bool
-_equalNullTest(NullTest *a, NullTest *b)
-{
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_SCALAR_FIELD(nulltesttype);
-
-       return true;
-}
-
-static bool
-_equalBooleanTest(BooleanTest *a, BooleanTest *b)
-{
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_SCALAR_FIELD(booltesttype);
-
-       return true;
-}
-
-static bool
-_equalConstraintTest(ConstraintTest *a, ConstraintTest *b)
-{
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_SCALAR_FIELD(testtype);
-       COMPARE_STRING_FIELD(name);
-       COMPARE_STRING_FIELD(domname);
-       COMPARE_NODE_FIELD(check_expr);
-
-       return true;
-}
-
-static bool
-_equalDomainConstraintValue(DomainConstraintValue *a, DomainConstraintValue *b)
-{
-       return true;
-}
-
-static bool
-_equalConstraintTestValue(ConstraintTestValue *a, ConstraintTestValue *b)
-{
-       COMPARE_SCALAR_FIELD(typeId);
-       COMPARE_SCALAR_FIELD(typeMod);
-
-       return true;
-}
-
 
 /*
  * Stuff from pg_list.h
@@ -1519,25 +1525,21 @@ equal(void *a, void *b)
 
        switch (nodeTag(a))
        {
-               case T_SubPlan:
-                       retval = _equalSubPlan(a, b);
-                       break;
-
+               /*
+                * PRIMITIVE NODES
+                */
                case T_Resdom:
                        retval = _equalResdom(a, b);
                        break;
-               case T_Fjoin:
-                       retval = _equalFjoin(a, b);
+               case T_Alias:
+                       retval = _equalAlias(a, b);
                        break;
-               case T_Expr:
-                       retval = _equalExpr(a, b);
+               case T_RangeVar:
+                       retval = _equalRangeVar(a, b);
                        break;
                case T_Var:
                        retval = _equalVar(a, b);
                        break;
-               case T_Oper:
-                       retval = _equalOper(a, b);
-                       break;
                case T_Const:
                        retval = _equalConst(a, b);
                        break;
@@ -1547,21 +1549,54 @@ equal(void *a, void *b)
                case T_Aggref:
                        retval = _equalAggref(a, b);
                        break;
+               case T_ArrayRef:
+                       retval = _equalArrayRef(a, b);
+                       break;
+               case T_FuncExpr:
+                       retval = _equalFuncExpr(a, b);
+                       break;
+               case T_OpExpr:
+                       retval = _equalOpExpr(a, b);
+                       break;
+               case T_DistinctExpr:
+                       retval = _equalDistinctExpr(a, b);
+                       break;
+               case T_BoolExpr:
+                       retval = _equalBoolExpr(a, b);
+                       break;
                case T_SubLink:
                        retval = _equalSubLink(a, b);
                        break;
-               case T_Func:
-                       retval = _equalFunc(a, b);
+               case T_SubPlanExpr:
+                       retval = _equalSubPlanExpr(a, b);
                        break;
                case T_FieldSelect:
                        retval = _equalFieldSelect(a, b);
                        break;
-               case T_ArrayRef:
-                       retval = _equalArrayRef(a, b);
-                       break;
                case T_RelabelType:
                        retval = _equalRelabelType(a, b);
                        break;
+               case T_CaseExpr:
+                       retval = _equalCaseExpr(a, b);
+                       break;
+               case T_CaseWhen:
+                       retval = _equalCaseWhen(a, b);
+                       break;
+               case T_NullTest:
+                       retval = _equalNullTest(a, b);
+                       break;
+               case T_BooleanTest:
+                       retval = _equalBooleanTest(a, b);
+                       break;
+               case T_ConstraintTest:
+                       retval = _equalConstraintTest(a, b);
+                       break;
+               case T_ConstraintTestValue:
+                       retval = _equalConstraintTestValue(a, b);
+                       break;
+               case T_TargetEntry:
+                       retval = _equalTargetEntry(a, b);
+                       break;
                case T_RangeTblRef:
                        retval = _equalRangeTblRef(a, b);
                        break;
@@ -1572,6 +1607,9 @@ equal(void *a, void *b)
                        retval = _equalJoinExpr(a, b);
                        break;
 
+                       /*
+                        * RELATION NODES
+                        */
                case T_PathKeyItem:
                        retval = _equalPathKeyItem(a, b);
                        break;
@@ -1582,6 +1620,9 @@ equal(void *a, void *b)
                        retval = _equalJoinInfo(a, b);
                        break;
 
+                       /*
+                        * LIST NODES
+                        */
                case T_List:
                        {
                                List       *la = (List *) a;
@@ -1612,6 +1653,9 @@ equal(void *a, void *b)
                        retval = _equalValue(a, b);
                        break;
 
+                       /*
+                        * PARSE NODES
+                        */
                case T_Query:
                        retval = _equalQuery(a, b);
                        break;
@@ -1844,12 +1888,6 @@ equal(void *a, void *b)
                case T_SortGroupBy:
                        retval = _equalSortGroupBy(a, b);
                        break;
-               case T_Alias:
-                       retval = _equalAlias(a, b);
-                       break;
-               case T_RangeVar:
-                       retval = _equalRangeVar(a, b);
-                       break;
                case T_RangeSubselect:
                        retval = _equalRangeSubselect(a, b);
                        break;
@@ -1871,9 +1909,6 @@ equal(void *a, void *b)
                case T_DefElem:
                        retval = _equalDefElem(a, b);
                        break;
-               case T_TargetEntry:
-                       retval = _equalTargetEntry(a, b);
-                       break;
                case T_RangeTblEntry:
                        retval = _equalRangeTblEntry(a, b);
                        break;
@@ -1884,24 +1919,6 @@ equal(void *a, void *b)
                        /* GroupClause is equivalent to SortClause */
                        retval = _equalSortClause(a, b);
                        break;
-               case T_CaseExpr:
-                       retval = _equalCaseExpr(a, b);
-                       break;
-               case T_CaseWhen:
-                       retval = _equalCaseWhen(a, b);
-                       break;
-               case T_NullTest:
-                       retval = _equalNullTest(a, b);
-                       break;
-               case T_BooleanTest:
-                       retval = _equalBooleanTest(a, b);
-                       break;
-               case T_ConstraintTest:
-                       retval = _equalConstraintTest(a, b);
-                       break;
-               case T_ConstraintTestValue:
-                       retval = _equalConstraintTestValue(a, b);
-                       break;
                case T_FkConstraint:
                        retval = _equalFkConstraint(a, b);
                        break;
index a97a6df..de13e94 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/*-------------------------------------------------------------------------
+ *
  * makefuncs.c
  *       creator functions for primitive nodes. The functions here are for
  *       the most frequently created nodes.
@@ -8,7 +9,9 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.36 2002/11/25 21:29:36 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.37 2002/12/12 15:49:28 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
@@ -50,29 +53,8 @@ makeSimpleA_Expr(int oper, const char *name,
 }
 
 /*
- * makeOper -
- *       creates an Oper node
- */
-Oper *
-makeOper(Oid opno,
-                Oid opid,
-                Oid opresulttype,
-                bool opretset)
-{
-       Oper       *oper = makeNode(Oper);
-
-       oper->opno = opno;
-       oper->opid = opid;
-       oper->opresulttype = opresulttype;
-       oper->opretset = opretset;
-       oper->op_fcache = NULL;
-       return oper;
-}
-
-/*
  * makeVar -
  *       creates a Var node
- *
  */
 Var *
 makeVar(Index varno,
@@ -104,10 +86,10 @@ makeVar(Index varno,
 
 /*
  * makeTargetEntry -
- *       creates a TargetEntry node(contains a Resdom)
+ *       creates a TargetEntry node (contains a Resdom)
  */
 TargetEntry *
-makeTargetEntry(Resdom *resdom, Node *expr)
+makeTargetEntry(Resdom *resdom, Expr *expr)
 {
        TargetEntry *rt = makeNode(TargetEntry);
 
@@ -189,6 +171,21 @@ makeNullConst(Oid consttype)
 }
 
 /*
+ * makeBoolExpr -
+ *       creates a BoolExpr node
+ */
+Expr *
+makeBoolExpr(BoolExprType boolop, List *args)
+{
+       BoolExpr   *b = makeNode(BoolExpr);
+
+       b->boolop = boolop;
+       b->args = args;
+
+       return (Expr *) b;
+}
+
+/*
  * makeAlias -
  *       creates an Alias node
  *
@@ -210,7 +207,7 @@ makeAlias(const char *aliasname, List *colnames)
  *       creates a RelabelType node
  */
 RelabelType *
-makeRelabelType(Node *arg, Oid rtype, int32 rtypmod, CoercionForm rformat)
+makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, CoercionForm rformat)
 {
        RelabelType *r = makeNode(RelabelType);
 
index f2bfb0a..299c910 100644 (file)
@@ -8,12 +8,10 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.19 2002/09/02 02:47:02 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.20 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-
-
 #include "postgres.h"
 
 #include "nodes/nodeFuncs.h"
@@ -21,6 +19,7 @@
 
 static bool var_is_inner(Var *var);
 
+
 /*
  * single_node -
  *       Returns t if node corresponds to a single-noded expression
@@ -79,41 +78,15 @@ var_is_rel(Var *var)
  *****************************************************************************/
 
 /*
- * replace_opid -
- *
- *             Given a oper node, resets the opfid field with the
- *             procedure OID (regproc id).
- *
- *             Returns the modified oper node.
+ * set_opfuncid -
  *
+ *             Set the opfuncid (procedure OID) in an OpExpr node,
+ *             if it hasn't been set already.
  */
-Oper *
-replace_opid(Oper *oper)
+void
+set_opfuncid(OpExpr *opexpr)
 {
-       oper->opid = get_opcode(oper->opno);
-       oper->op_fcache = NULL;
-       return oper;
+       if (opexpr->opfuncid == InvalidOid)
+               opexpr->opfuncid = get_opcode(opexpr->opno);
+       opexpr->op_fcache = NULL;               /* XXX will go away soon */
 }
-
-/*****************************************************************************
- *             constant (CONST, PARAM) nodes
- *****************************************************************************/
-
-#ifdef NOT_USED
-/*
- * non_null -
- *             Returns t if the node is a non-null constant, e.g., if the node has a
- *             valid `constvalue' field.
- */
-bool
-non_null(Expr *c)
-{
-
-       if (IsA(c, Const) &&
-               !((Const *) c)->constisnull)
-               return true;
-       else
-               return false;
-}
-
-#endif
index 2c25400..bd44816 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.186 2002/12/05 15:50:35 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.187 2002/12/12 15:49:28 tgl Exp $
  *
  * NOTES
  *       Every node type that can appear in stored rules' parsetrees *must*
@@ -99,9 +99,9 @@
 
 #define booltostr(x)  ((x) ? "true" : "false")
 
-static void _outDatum(StringInfo str, Datum value, int typlen, bool typbyval);
 static void _outNode(StringInfo str, void *obj);
 
+
 /*
  * _outToken
  *       Convert an ordinary string (eg, an identifier) into a form that
@@ -172,196 +172,41 @@ _outOidList(StringInfo str, List *list)
        appendStringInfoChar(str, ')');
 }
 
+/*
+ * Print the value of a Datum given its type.
+ */
 static void
-_outCreateStmt(StringInfo str, CreateStmt *node)
-{
-       WRITE_NODE_TYPE("CREATE");
-
-       WRITE_NODE_FIELD(relation);
-       WRITE_NODE_FIELD(tableElts);
-       WRITE_NODE_FIELD(inhRelations);
-       WRITE_NODE_FIELD(constraints);
-       WRITE_BOOL_FIELD(hasoids);
-       WRITE_ENUM_FIELD(oncommit, OnCommitAction);
-}
-
-static void
-_outIndexStmt(StringInfo str, IndexStmt *node)
-{
-       WRITE_NODE_TYPE("INDEX");
-
-       WRITE_STRING_FIELD(idxname);
-       WRITE_NODE_FIELD(relation);
-       WRITE_STRING_FIELD(accessMethod);
-       WRITE_NODE_FIELD(indexParams);
-       WRITE_NODE_FIELD(whereClause);
-       WRITE_NODE_FIELD(rangetable);
-       WRITE_BOOL_FIELD(unique);
-       WRITE_BOOL_FIELD(primary);
-       WRITE_BOOL_FIELD(isconstraint);
-}
-
-static void
-_outNotifyStmt(StringInfo str, NotifyStmt *node)
-{
-       WRITE_NODE_TYPE("NOTIFY");
-
-       WRITE_NODE_FIELD(relation);
-}
-
-static void
-_outSelectStmt(StringInfo str, SelectStmt *node)
-{
-       WRITE_NODE_TYPE("SELECT");
-
-       /* XXX this is pretty durn incomplete */
-       WRITE_NODE_FIELD(whereClause);
-}
-
-static void
-_outFuncCall(StringInfo str, FuncCall *node)
-{
-       WRITE_NODE_TYPE("FUNCCALL");
-
-       WRITE_NODE_FIELD(funcname);
-       WRITE_NODE_FIELD(args);
-       WRITE_BOOL_FIELD(agg_star);
-       WRITE_BOOL_FIELD(agg_distinct);
-}
-
-static void
-_outColumnDef(StringInfo str, ColumnDef *node)
-{
-       WRITE_NODE_TYPE("COLUMNDEF");
-
-       WRITE_STRING_FIELD(colname);
-       WRITE_NODE_FIELD(typename);
-       WRITE_INT_FIELD(inhcount);
-       WRITE_BOOL_FIELD(is_local);
-       WRITE_BOOL_FIELD(is_not_null);
-       WRITE_NODE_FIELD(raw_default);
-       WRITE_STRING_FIELD(cooked_default);
-       WRITE_NODE_FIELD(constraints);
-       WRITE_NODE_FIELD(support);
-}
-
-static void
-_outTypeName(StringInfo str, TypeName *node)
-{
-       WRITE_NODE_TYPE("TYPENAME");
-
-       WRITE_NODE_FIELD(names);
-       WRITE_OID_FIELD(typeid);
-       WRITE_BOOL_FIELD(timezone);
-       WRITE_BOOL_FIELD(setof);
-       WRITE_BOOL_FIELD(pct_type);
-       WRITE_INT_FIELD(typmod);
-       WRITE_NODE_FIELD(arrayBounds);
-}
-
-static void
-_outTypeCast(StringInfo str, TypeCast *node)
-{
-       WRITE_NODE_TYPE("TYPECAST");
-
-       WRITE_NODE_FIELD(arg);
-       WRITE_NODE_FIELD(typename);
-}
-
-static void
-_outIndexElem(StringInfo str, IndexElem *node)
-{
-       WRITE_NODE_TYPE("INDEXELEM");
-
-       WRITE_STRING_FIELD(name);
-       WRITE_NODE_FIELD(funcname);
-       WRITE_NODE_FIELD(args);
-       WRITE_NODE_FIELD(opclass);
-}
-
-static void
-_outQuery(StringInfo str, Query *node)
+_outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
 {
-       WRITE_NODE_TYPE("QUERY");
+       Size            length,
+                               i;
+       char       *s;
 
-       WRITE_ENUM_FIELD(commandType, CmdType);
-       WRITE_ENUM_FIELD(querySource, QuerySource);
+       length = datumGetSize(value, typbyval, typlen);
 
-       /*
-        * Hack to work around missing outfuncs routines for a lot of the
-        * utility-statement node types.  (The only one we actually *need* for
-        * rules support is NotifyStmt.)  Someday we ought to support 'em all,
-        * but for the meantime do this to avoid getting lots of warnings when
-        * running with debug_print_parse on.
-        */
-       if (node->utilityStmt)
+       if (typbyval)
        {
-               switch (nodeTag(node->utilityStmt))
+               s = (char *) (&value);
+               appendStringInfo(str, "%u [ ", (unsigned int) length);
+               for (i = 0; i < (Size) sizeof(Datum); i++)
+                       appendStringInfo(str, "%d ", (int) (s[i]));
+               appendStringInfo(str, "]");
+       }
+       else
+       {
+               s = (char *) DatumGetPointer(value);
+               if (!PointerIsValid(s))
+                       appendStringInfo(str, "0 [ ]");
+               else
                {
-                       case T_CreateStmt:
-                       case T_IndexStmt:
-                       case T_NotifyStmt:
-                               WRITE_NODE_FIELD(utilityStmt);
-                               break;
-                       default:
-                               appendStringInfo(str, " :utilityStmt ?");
-                               break;
+                       appendStringInfo(str, "%u [ ", (unsigned int) length);
+                       for (i = 0; i < length; i++)
+                               appendStringInfo(str, "%d ", (int) (s[i]));
+                       appendStringInfo(str, "]");
                }
        }
-       else
-               appendStringInfo(str, " :utilityStmt <>");
-
-       WRITE_INT_FIELD(resultRelation);
-       WRITE_NODE_FIELD(into);
-       WRITE_BOOL_FIELD(isPortal);
-       WRITE_BOOL_FIELD(isBinary);
-       WRITE_BOOL_FIELD(hasAggs);
-       WRITE_BOOL_FIELD(hasSubLinks);
-       WRITE_NODE_FIELD(rtable);
-       WRITE_NODE_FIELD(jointree);
-       WRITE_INTLIST_FIELD(rowMarks);
-       WRITE_NODE_FIELD(targetList);
-       WRITE_NODE_FIELD(groupClause);
-       WRITE_NODE_FIELD(havingQual);
-       WRITE_NODE_FIELD(distinctClause);
-       WRITE_NODE_FIELD(sortClause);
-       WRITE_NODE_FIELD(limitOffset);
-       WRITE_NODE_FIELD(limitCount);
-       WRITE_NODE_FIELD(setOperations);
-       WRITE_INTLIST_FIELD(resultRelations);
-
-       /* planner-internal fields are not written out */
-}
-
-static void
-_outSortClause(StringInfo str, SortClause *node)
-{
-       WRITE_NODE_TYPE("SORTCLAUSE");
-
-       WRITE_UINT_FIELD(tleSortGroupRef);
-       WRITE_OID_FIELD(sortop);
-}
-
-static void
-_outGroupClause(StringInfo str, GroupClause *node)
-{
-       WRITE_NODE_TYPE("GROUPCLAUSE");
-
-       WRITE_UINT_FIELD(tleSortGroupRef);
-       WRITE_OID_FIELD(sortop);
 }
 
-static void
-_outSetOperationStmt(StringInfo str, SetOperationStmt *node)
-{
-       WRITE_NODE_TYPE("SETOPERATIONSTMT");
-
-       WRITE_ENUM_FIELD(op, SetOperation);
-       WRITE_BOOL_FIELD(all);
-       WRITE_NODE_FIELD(larg);
-       WRITE_NODE_FIELD(rarg);
-       WRITE_OIDLIST_FIELD(colTypes);
-}
 
 /*
  *     Stuff from plannodes.h
@@ -631,19 +476,6 @@ _outHash(StringInfo str, Hash *node)
        WRITE_NODE_FIELD(hashkeys);
 }
 
-static void
-_outSubPlan(StringInfo str, SubPlan *node)
-{
-       WRITE_NODE_TYPE("SUBPLAN");
-
-       WRITE_NODE_FIELD(plan);
-       WRITE_INT_FIELD(plan_id);
-       WRITE_NODE_FIELD(rtable);
-       WRITE_INTLIST_FIELD(setParam);
-       WRITE_INTLIST_FIELD(parParam);
-       WRITE_NODE_FIELD(sublink);
-}
-
 /*****************************************************************************
  *
  *     Stuff from primnodes.h.
@@ -666,58 +498,42 @@ _outResdom(StringInfo str, Resdom *node)
 }
 
 static void
-_outExpr(StringInfo str, Expr *node)
+_outAlias(StringInfo str, Alias *node)
 {
-       char       *opstr = NULL;
-
-       WRITE_NODE_TYPE("EXPR");
-
-       WRITE_OID_FIELD(typeOid);
-
-       /* do-it-yourself enum representation */
-       switch (node->opType)
-       {
-               case OP_EXPR:
-                       opstr = "op";
-                       break;
-               case DISTINCT_EXPR:
-                       opstr = "distinct";
-                       break;
-               case FUNC_EXPR:
-                       opstr = "func";
-                       break;
-               case OR_EXPR:
-                       opstr = "or";
-                       break;
-               case AND_EXPR:
-                       opstr = "and";
-                       break;
-               case NOT_EXPR:
-                       opstr = "not";
-                       break;
-               case SUBPLAN_EXPR:
-                       opstr = "subp";
-                       break;
-       }
-       appendStringInfo(str, " :opType ");
-       _outToken(str, opstr);
+       WRITE_NODE_TYPE("ALIAS");
 
-       WRITE_NODE_FIELD(oper);
-       WRITE_NODE_FIELD(args);
+       WRITE_STRING_FIELD(aliasname);
+       WRITE_NODE_FIELD(colnames);
 }
 
 static void
-_outVar(StringInfo str, Var *node)
+_outRangeVar(StringInfo str, RangeVar *node)
 {
-       WRITE_NODE_TYPE("VAR");
+       WRITE_NODE_TYPE("RANGEVAR");
 
-       WRITE_UINT_FIELD(varno);
-       WRITE_INT_FIELD(varattno);
-       WRITE_OID_FIELD(vartype);
-       WRITE_INT_FIELD(vartypmod);
-       WRITE_UINT_FIELD(varlevelsup);
-       WRITE_UINT_FIELD(varnoold);
-       WRITE_INT_FIELD(varoattno);
+       /*
+        * we deliberately ignore catalogname here, since it is presently not
+        * semantically meaningful
+        */
+       WRITE_STRING_FIELD(schemaname);
+       WRITE_STRING_FIELD(relname);
+       WRITE_ENUM_FIELD(inhOpt, InhOption);
+       WRITE_BOOL_FIELD(istemp);
+       WRITE_NODE_FIELD(alias);
+}
+
+static void
+_outVar(StringInfo str, Var *node)
+{
+       WRITE_NODE_TYPE("VAR");
+
+       WRITE_UINT_FIELD(varno);
+       WRITE_INT_FIELD(varattno);
+       WRITE_OID_FIELD(vartype);
+       WRITE_INT_FIELD(vartypmod);
+       WRITE_UINT_FIELD(varlevelsup);
+       WRITE_UINT_FIELD(varnoold);
+       WRITE_INT_FIELD(varoattno);
 }
 
 static void
@@ -738,6 +554,17 @@ _outConst(StringInfo str, Const *node)
 }
 
 static void
+_outParam(StringInfo str, Param *node)
+{
+       WRITE_NODE_TYPE("PARAM");
+
+       WRITE_INT_FIELD(paramkind);
+       WRITE_INT_FIELD(paramid);
+       WRITE_STRING_FIELD(paramname);
+       WRITE_OID_FIELD(paramtype);
+}
+
+static void
 _outAggref(StringInfo str, Aggref *node)
 {
        WRITE_NODE_TYPE("AGGREF");
@@ -747,19 +574,6 @@ _outAggref(StringInfo str, Aggref *node)
        WRITE_NODE_FIELD(target);
        WRITE_BOOL_FIELD(aggstar);
        WRITE_BOOL_FIELD(aggdistinct);
-       /* aggno is not saved since it is just executor state */
-}
-
-static void
-_outSubLink(StringInfo str, SubLink *node)
-{
-       WRITE_NODE_TYPE("SUBLINK");
-
-       WRITE_ENUM_FIELD(subLinkType, SubLinkType);
-       WRITE_BOOL_FIELD(useor);
-       WRITE_NODE_FIELD(lefthand);
-       WRITE_NODE_FIELD(oper);
-       WRITE_NODE_FIELD(subselect);
 }
 
 static void
@@ -779,36 +593,92 @@ _outArrayRef(StringInfo str, ArrayRef *node)
 }
 
 static void
-_outFunc(StringInfo str, Func *node)
+_outFuncExpr(StringInfo str, FuncExpr *node)
 {
-       WRITE_NODE_TYPE("FUNC");
+       WRITE_NODE_TYPE("FUNCEXPR");
 
        WRITE_OID_FIELD(funcid);
        WRITE_OID_FIELD(funcresulttype);
        WRITE_BOOL_FIELD(funcretset);
        WRITE_ENUM_FIELD(funcformat, CoercionForm);
+       WRITE_NODE_FIELD(args);
+}
+
+static void
+_outOpExpr(StringInfo str, OpExpr *node)
+{
+       WRITE_NODE_TYPE("OPEXPR");
+
+       WRITE_OID_FIELD(opno);
+       WRITE_OID_FIELD(opfuncid);
+       WRITE_OID_FIELD(opresulttype);
+       WRITE_BOOL_FIELD(opretset);
+       WRITE_NODE_FIELD(args);
 }
 
 static void
-_outOper(StringInfo str, Oper *node)
+_outDistinctExpr(StringInfo str, DistinctExpr *node)
 {
-       WRITE_NODE_TYPE("OPER");
+       WRITE_NODE_TYPE("DISTINCTEXPR");
 
        WRITE_OID_FIELD(opno);
-       WRITE_OID_FIELD(opid);
+       WRITE_OID_FIELD(opfuncid);
        WRITE_OID_FIELD(opresulttype);
        WRITE_BOOL_FIELD(opretset);
+       WRITE_NODE_FIELD(args);
 }
 
 static void
-_outParam(StringInfo str, Param *node)
+_outBoolExpr(StringInfo str, BoolExpr *node)
 {
-       WRITE_NODE_TYPE("PARAM");
+       char       *opstr = NULL;
 
-       WRITE_INT_FIELD(paramkind);
-       WRITE_INT_FIELD(paramid);
-       WRITE_STRING_FIELD(paramname);
-       WRITE_OID_FIELD(paramtype);
+       WRITE_NODE_TYPE("BOOLEXPR");
+
+       /* do-it-yourself enum representation */
+       switch (node->boolop)
+       {
+               case AND_EXPR:
+                       opstr = "and";
+                       break;
+               case OR_EXPR:
+                       opstr = "or";
+                       break;
+               case NOT_EXPR:
+                       opstr = "not";
+                       break;
+       }
+       appendStringInfo(str, " :boolop ");
+       _outToken(str, opstr);
+
+       WRITE_NODE_FIELD(args);
+}
+
+static void
+_outSubLink(StringInfo str, SubLink *node)
+{
+       WRITE_NODE_TYPE("SUBLINK");
+
+       WRITE_ENUM_FIELD(subLinkType, SubLinkType);
+       WRITE_BOOL_FIELD(useor);
+       WRITE_NODE_FIELD(lefthand);
+       WRITE_NODE_FIELD(oper);
+       WRITE_NODE_FIELD(subselect);
+}
+
+static void
+_outSubPlanExpr(StringInfo str, SubPlanExpr *node)
+{
+       WRITE_NODE_TYPE("SUBPLANEXPR");
+
+       WRITE_OID_FIELD(typeOid);
+       WRITE_NODE_FIELD(plan);
+       WRITE_INT_FIELD(plan_id);
+       WRITE_NODE_FIELD(rtable);
+       WRITE_INTLIST_FIELD(setParam);
+       WRITE_INTLIST_FIELD(parParam);
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(sublink);
 }
 
 static void
@@ -834,35 +704,62 @@ _outRelabelType(StringInfo str, RelabelType *node)
 }
 
 static void
-_outRangeTblRef(StringInfo str, RangeTblRef *node)
+_outCaseExpr(StringInfo str, CaseExpr *node)
 {
-       WRITE_NODE_TYPE("RANGETBLREF");
+       WRITE_NODE_TYPE("CASE");
 
-       WRITE_INT_FIELD(rtindex);
+       WRITE_OID_FIELD(casetype);
+       WRITE_NODE_FIELD(arg);
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(defresult);
 }
 
 static void
-_outJoinExpr(StringInfo str, JoinExpr *node)
+_outCaseWhen(StringInfo str, CaseWhen *node)
 {
-       WRITE_NODE_TYPE("JOINEXPR");
+       WRITE_NODE_TYPE("WHEN");
 
-       WRITE_ENUM_FIELD(jointype, JoinType);
-       WRITE_BOOL_FIELD(isNatural);
-       WRITE_NODE_FIELD(larg);
-       WRITE_NODE_FIELD(rarg);
-       WRITE_NODE_FIELD(using);
-       WRITE_NODE_FIELD(quals);
-       WRITE_NODE_FIELD(alias);
-       WRITE_INT_FIELD(rtindex);
+       WRITE_NODE_FIELD(expr);
+       WRITE_NODE_FIELD(result);
 }
 
 static void
-_outFromExpr(StringInfo str, FromExpr *node)
+_outNullTest(StringInfo str, NullTest *node)
 {
-       WRITE_NODE_TYPE("FROMEXPR");
+       WRITE_NODE_TYPE("NULLTEST");
 
-       WRITE_NODE_FIELD(fromlist);
-       WRITE_NODE_FIELD(quals);
+       WRITE_NODE_FIELD(arg);
+       WRITE_ENUM_FIELD(nulltesttype, NullTestType);
+}
+
+static void
+_outBooleanTest(StringInfo str, BooleanTest *node)
+{
+       WRITE_NODE_TYPE("BOOLEANTEST");
+
+       WRITE_NODE_FIELD(arg);
+       WRITE_ENUM_FIELD(booltesttype, BoolTestType);
+}
+
+static void
+_outConstraintTest(StringInfo str, ConstraintTest *node)
+{
+       WRITE_NODE_TYPE("CONSTRAINTTEST");
+
+       WRITE_NODE_FIELD(arg);
+       WRITE_ENUM_FIELD(testtype, ConstraintTestType);
+       WRITE_STRING_FIELD(name);
+       WRITE_STRING_FIELD(domname);
+       WRITE_NODE_FIELD(check_expr);
+}
+
+static void
+_outConstraintTestValue(StringInfo str, ConstraintTestValue *node)
+{
+       WRITE_NODE_TYPE("CONSTRAINTTESTVALUE");
+
+       WRITE_OID_FIELD(typeId);
+       WRITE_INT_FIELD(typeMod);
 }
 
 static void
@@ -871,58 +768,47 @@ _outTargetEntry(StringInfo str, TargetEntry *node)
        WRITE_NODE_TYPE("TARGETENTRY");
 
        WRITE_NODE_FIELD(resdom);
-       /* fjoin not supported ... */
        WRITE_NODE_FIELD(expr);
 }
 
 static void
-_outAlias(StringInfo str, Alias *node)
+_outRangeTblRef(StringInfo str, RangeTblRef *node)
 {
-       WRITE_NODE_TYPE("ALIAS");
+       WRITE_NODE_TYPE("RANGETBLREF");
 
-       WRITE_STRING_FIELD(aliasname);
-       WRITE_NODE_FIELD(colnames);
+       WRITE_INT_FIELD(rtindex);
 }
 
 static void
-_outRangeTblEntry(StringInfo str, RangeTblEntry *node)
+_outJoinExpr(StringInfo str, JoinExpr *node)
 {
-       WRITE_NODE_TYPE("RTE");
+       WRITE_NODE_TYPE("JOINEXPR");
 
-       /* put alias + eref first to make dump more legible */
+       WRITE_ENUM_FIELD(jointype, JoinType);
+       WRITE_BOOL_FIELD(isNatural);
+       WRITE_NODE_FIELD(larg);
+       WRITE_NODE_FIELD(rarg);
+       WRITE_NODE_FIELD(using);
+       WRITE_NODE_FIELD(quals);
        WRITE_NODE_FIELD(alias);
-       WRITE_NODE_FIELD(eref);
-       WRITE_ENUM_FIELD(rtekind, RTEKind);
+       WRITE_INT_FIELD(rtindex);
+}
 
-       switch (node->rtekind)
-       {
-               case RTE_RELATION:
-               case RTE_SPECIAL:
-                       WRITE_OID_FIELD(relid);
-                       break;
-               case RTE_SUBQUERY:
-                       WRITE_NODE_FIELD(subquery);
-                       break;
-               case RTE_FUNCTION:
-                       WRITE_NODE_FIELD(funcexpr);
-                       WRITE_NODE_FIELD(coldeflist);
-                       break;
-               case RTE_JOIN:
-                       WRITE_ENUM_FIELD(jointype, JoinType);
-                       WRITE_NODE_FIELD(joinaliasvars);
-                       break;
-               default:
-                       elog(ERROR, "bogus rte kind %d", (int) node->rtekind);
-                       break;
-       }
+static void
+_outFromExpr(StringInfo str, FromExpr *node)
+{
+       WRITE_NODE_TYPE("FROMEXPR");
 
-       WRITE_BOOL_FIELD(inh);
-       WRITE_BOOL_FIELD(inFromCl);
-       WRITE_BOOL_FIELD(checkForRead);
-       WRITE_BOOL_FIELD(checkForWrite);
-       WRITE_OID_FIELD(checkAsUser);
+       WRITE_NODE_FIELD(fromlist);
+       WRITE_NODE_FIELD(quals);
 }
 
+/*****************************************************************************
+ *
+ *     Stuff from relation.h.
+ *
+ *****************************************************************************/
+
 /*
  * print the basic stuff of all nodes that inherit from Path
  *
@@ -1078,39 +964,240 @@ _outJoinInfo(StringInfo str, JoinInfo *node)
        WRITE_NODE_FIELD(jinfo_restrictinfo);
 }
 
-/*
- * Print the value of a Datum given its type.
- */
+/*****************************************************************************
+ *
+ *     Stuff from parsenodes.h.
+ *
+ *****************************************************************************/
+
 static void
-_outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
+_outCreateStmt(StringInfo str, CreateStmt *node)
 {
-       Size            length,
-                               i;
-       char       *s;
+       WRITE_NODE_TYPE("CREATE");
 
-       length = datumGetSize(value, typbyval, typlen);
+       WRITE_NODE_FIELD(relation);
+       WRITE_NODE_FIELD(tableElts);
+       WRITE_NODE_FIELD(inhRelations);
+       WRITE_NODE_FIELD(constraints);
+       WRITE_BOOL_FIELD(hasoids);
+       WRITE_ENUM_FIELD(oncommit, OnCommitAction);
+}
 
-       if (typbyval)
-       {
-               s = (char *) (&value);
-               appendStringInfo(str, "%u [ ", (unsigned int) length);
-               for (i = 0; i < (Size) sizeof(Datum); i++)
-                       appendStringInfo(str, "%d ", (int) (s[i]));
-               appendStringInfo(str, "]");
-       }
-       else
+static void
+_outIndexStmt(StringInfo str, IndexStmt *node)
+{
+       WRITE_NODE_TYPE("INDEX");
+
+       WRITE_STRING_FIELD(idxname);
+       WRITE_NODE_FIELD(relation);
+       WRITE_STRING_FIELD(accessMethod);
+       WRITE_NODE_FIELD(indexParams);
+       WRITE_NODE_FIELD(whereClause);
+       WRITE_NODE_FIELD(rangetable);
+       WRITE_BOOL_FIELD(unique);
+       WRITE_BOOL_FIELD(primary);
+       WRITE_BOOL_FIELD(isconstraint);
+}
+
+static void
+_outNotifyStmt(StringInfo str, NotifyStmt *node)
+{
+       WRITE_NODE_TYPE("NOTIFY");
+
+       WRITE_NODE_FIELD(relation);
+}
+
+static void
+_outSelectStmt(StringInfo str, SelectStmt *node)
+{
+       WRITE_NODE_TYPE("SELECT");
+
+       /* XXX this is pretty durn incomplete */
+       WRITE_NODE_FIELD(whereClause);
+}
+
+static void
+_outFuncCall(StringInfo str, FuncCall *node)
+{
+       WRITE_NODE_TYPE("FUNCCALL");
+
+       WRITE_NODE_FIELD(funcname);
+       WRITE_NODE_FIELD(args);
+       WRITE_BOOL_FIELD(agg_star);
+       WRITE_BOOL_FIELD(agg_distinct);
+}
+
+static void
+_outColumnDef(StringInfo str, ColumnDef *node)
+{
+       WRITE_NODE_TYPE("COLUMNDEF");
+
+       WRITE_STRING_FIELD(colname);
+       WRITE_NODE_FIELD(typename);
+       WRITE_INT_FIELD(inhcount);
+       WRITE_BOOL_FIELD(is_local);
+       WRITE_BOOL_FIELD(is_not_null);
+       WRITE_NODE_FIELD(raw_default);
+       WRITE_STRING_FIELD(cooked_default);
+       WRITE_NODE_FIELD(constraints);
+       WRITE_NODE_FIELD(support);
+}
+
+static void
+_outTypeName(StringInfo str, TypeName *node)
+{
+       WRITE_NODE_TYPE("TYPENAME");
+
+       WRITE_NODE_FIELD(names);
+       WRITE_OID_FIELD(typeid);
+       WRITE_BOOL_FIELD(timezone);
+       WRITE_BOOL_FIELD(setof);
+       WRITE_BOOL_FIELD(pct_type);
+       WRITE_INT_FIELD(typmod);
+       WRITE_NODE_FIELD(arrayBounds);
+}
+
+static void
+_outTypeCast(StringInfo str, TypeCast *node)
+{
+       WRITE_NODE_TYPE("TYPECAST");
+
+       WRITE_NODE_FIELD(arg);
+       WRITE_NODE_FIELD(typename);
+}
+
+static void
+_outIndexElem(StringInfo str, IndexElem *node)
+{
+       WRITE_NODE_TYPE("INDEXELEM");
+
+       WRITE_STRING_FIELD(name);
+       WRITE_NODE_FIELD(funcname);
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(opclass);
+}
+
+static void
+_outQuery(StringInfo str, Query *node)
+{
+       WRITE_NODE_TYPE("QUERY");
+
+       WRITE_ENUM_FIELD(commandType, CmdType);
+       WRITE_ENUM_FIELD(querySource, QuerySource);
+
+       /*
+        * Hack to work around missing outfuncs routines for a lot of the
+        * utility-statement node types.  (The only one we actually *need* for
+        * rules support is NotifyStmt.)  Someday we ought to support 'em all,
+        * but for the meantime do this to avoid getting lots of warnings when
+        * running with debug_print_parse on.
+        */
+       if (node->utilityStmt)
        {
-               s = (char *) DatumGetPointer(value);
-               if (!PointerIsValid(s))
-                       appendStringInfo(str, "0 [ ]");
-               else
+               switch (nodeTag(node->utilityStmt))
                {
-                       appendStringInfo(str, "%u [ ", (unsigned int) length);
-                       for (i = 0; i < length; i++)
-                               appendStringInfo(str, "%d ", (int) (s[i]));
-                       appendStringInfo(str, "]");
+                       case T_CreateStmt:
+                       case T_IndexStmt:
+                       case T_NotifyStmt:
+                               WRITE_NODE_FIELD(utilityStmt);
+                               break;
+                       default:
+                               appendStringInfo(str, " :utilityStmt ?");
+                               break;
                }
        }
+       else
+               appendStringInfo(str, " :utilityStmt <>");
+
+       WRITE_INT_FIELD(resultRelation);
+       WRITE_NODE_FIELD(into);
+       WRITE_BOOL_FIELD(isPortal);
+       WRITE_BOOL_FIELD(isBinary);
+       WRITE_BOOL_FIELD(hasAggs);
+       WRITE_BOOL_FIELD(hasSubLinks);
+       WRITE_NODE_FIELD(rtable);
+       WRITE_NODE_FIELD(jointree);
+       WRITE_INTLIST_FIELD(rowMarks);
+       WRITE_NODE_FIELD(targetList);
+       WRITE_NODE_FIELD(groupClause);
+       WRITE_NODE_FIELD(havingQual);
+       WRITE_NODE_FIELD(distinctClause);
+       WRITE_NODE_FIELD(sortClause);
+       WRITE_NODE_FIELD(limitOffset);
+       WRITE_NODE_FIELD(limitCount);
+       WRITE_NODE_FIELD(setOperations);
+       WRITE_INTLIST_FIELD(resultRelations);
+
+       /* planner-internal fields are not written out */
+}
+
+static void
+_outSortClause(StringInfo str, SortClause *node)
+{
+       WRITE_NODE_TYPE("SORTCLAUSE");
+
+       WRITE_UINT_FIELD(tleSortGroupRef);
+       WRITE_OID_FIELD(sortop);
+}
+
+static void
+_outGroupClause(StringInfo str, GroupClause *node)
+{
+       WRITE_NODE_TYPE("GROUPCLAUSE");
+
+       WRITE_UINT_FIELD(tleSortGroupRef);
+       WRITE_OID_FIELD(sortop);
+}
+
+static void
+_outSetOperationStmt(StringInfo str, SetOperationStmt *node)
+{
+       WRITE_NODE_TYPE("SETOPERATIONSTMT");
+
+       WRITE_ENUM_FIELD(op, SetOperation);
+       WRITE_BOOL_FIELD(all);
+       WRITE_NODE_FIELD(larg);
+       WRITE_NODE_FIELD(rarg);
+       WRITE_OIDLIST_FIELD(colTypes);
+}
+
+static void
+_outRangeTblEntry(StringInfo str, RangeTblEntry *node)
+{
+       WRITE_NODE_TYPE("RTE");
+
+       /* put alias + eref first to make dump more legible */
+       WRITE_NODE_FIELD(alias);
+       WRITE_NODE_FIELD(eref);
+       WRITE_ENUM_FIELD(rtekind, RTEKind);
+
+       switch (node->rtekind)
+       {
+               case RTE_RELATION:
+               case RTE_SPECIAL:
+                       WRITE_OID_FIELD(relid);
+                       break;
+               case RTE_SUBQUERY:
+                       WRITE_NODE_FIELD(subquery);
+                       break;
+               case RTE_FUNCTION:
+                       WRITE_NODE_FIELD(funcexpr);
+                       WRITE_NODE_FIELD(coldeflist);
+                       break;
+               case RTE_JOIN:
+                       WRITE_ENUM_FIELD(jointype, JoinType);
+                       WRITE_NODE_FIELD(joinaliasvars);
+                       break;
+               default:
+                       elog(ERROR, "bogus rte kind %d", (int) node->rtekind);
+                       break;
+       }
+
+       WRITE_BOOL_FIELD(inh);
+       WRITE_BOOL_FIELD(inFromCl);
+       WRITE_BOOL_FIELD(checkForRead);
+       WRITE_BOOL_FIELD(checkForWrite);
+       WRITE_OID_FIELD(checkAsUser);
 }
 
 static void
@@ -1175,22 +1262,6 @@ _outValue(StringInfo str, Value *value)
 }
 
 static void
-_outRangeVar(StringInfo str, RangeVar *node)
-{
-       WRITE_NODE_TYPE("RANGEVAR");
-
-       /*
-        * we deliberately ignore catalogname here, since it is presently not
-        * semantically meaningful
-        */
-       WRITE_STRING_FIELD(schemaname);
-       WRITE_STRING_FIELD(relname);
-       WRITE_ENUM_FIELD(inhOpt, InhOption);
-       WRITE_BOOL_FIELD(istemp);
-       WRITE_NODE_FIELD(alias);
-}
-
-static void
 _outColumnRef(StringInfo str, ColumnRef *node)
 {
        WRITE_NODE_TYPE("COLUMNREF");
@@ -1229,6 +1300,12 @@ _outExprFieldSelect(StringInfo str, ExprFieldSelect *node)
 }
 
 static void
+_outDomainConstraintValue(StringInfo str, DomainConstraintValue *node)
+{
+       WRITE_NODE_TYPE("DOMAINCONSTRAINTVALUE");
+}
+
+static void
 _outConstraint(StringInfo str, Constraint *node)
 {
        WRITE_NODE_TYPE("CONSTRAINT");
@@ -1287,71 +1364,6 @@ _outFkConstraint(StringInfo str, FkConstraint *node)
        WRITE_BOOL_FIELD(skip_validation);
 }
 
-static void
-_outCaseExpr(StringInfo str, CaseExpr *node)
-{
-       WRITE_NODE_TYPE("CASE");
-
-       WRITE_OID_FIELD(casetype);
-       WRITE_NODE_FIELD(arg);
-       WRITE_NODE_FIELD(args);
-       WRITE_NODE_FIELD(defresult);
-}
-
-static void
-_outCaseWhen(StringInfo str, CaseWhen *node)
-{
-       WRITE_NODE_TYPE("WHEN");
-
-       WRITE_NODE_FIELD(expr);
-       WRITE_NODE_FIELD(result);
-}
-
-static void
-_outNullTest(StringInfo str, NullTest *node)
-{
-       WRITE_NODE_TYPE("NULLTEST");
-
-       WRITE_NODE_FIELD(arg);
-       WRITE_ENUM_FIELD(nulltesttype, NullTestType);
-}
-
-static void
-_outBooleanTest(StringInfo str, BooleanTest *node)
-{
-       WRITE_NODE_TYPE("BOOLEANTEST");
-
-       WRITE_NODE_FIELD(arg);
-       WRITE_ENUM_FIELD(booltesttype, BoolTestType);
-}
-
-static void
-_outConstraintTest(StringInfo str, ConstraintTest *node)
-{
-       WRITE_NODE_TYPE("CONSTRAINTTEST");
-
-       WRITE_NODE_FIELD(arg);
-       WRITE_ENUM_FIELD(testtype, ConstraintTestType);
-       WRITE_STRING_FIELD(name);
-       WRITE_STRING_FIELD(domname);
-       WRITE_NODE_FIELD(check_expr);
-}
-
-static void
-_outDomainConstraintValue(StringInfo str, DomainConstraintValue *node)
-{
-       WRITE_NODE_TYPE("DOMAINCONSTRAINTVALUE");
-}
-
-static void
-_outConstraintTestValue(StringInfo str, ConstraintTestValue *node)
-{
-       WRITE_NODE_TYPE("CONSTRAINTTESTVALUE");
-
-       WRITE_OID_FIELD(typeId);
-       WRITE_INT_FIELD(typeMod);
-}
-
 
 /*
  * _outNode -
@@ -1392,42 +1404,6 @@ _outNode(StringInfo str, void *obj)
                appendStringInfoChar(str, '{');
                switch (nodeTag(obj))
                {
-                       case T_CreateStmt:
-                               _outCreateStmt(str, obj);
-                               break;
-                       case T_IndexStmt:
-                               _outIndexStmt(str, obj);
-                               break;
-                       case T_NotifyStmt:
-                               _outNotifyStmt(str, obj);
-                               break;
-                       case T_SelectStmt:
-                               _outSelectStmt(str, obj);
-                               break;
-                       case T_ColumnDef:
-                               _outColumnDef(str, obj);
-                               break;
-                       case T_TypeName:
-                               _outTypeName(str, obj);
-                               break;
-                       case T_TypeCast:
-                               _outTypeCast(str, obj);
-                               break;
-                       case T_IndexElem:
-                               _outIndexElem(str, obj);
-                               break;
-                       case T_Query:
-                               _outQuery(str, obj);
-                               break;
-                       case T_SortClause:
-                               _outSortClause(str, obj);
-                               break;
-                       case T_GroupClause:
-                               _outGroupClause(str, obj);
-                               break;
-                       case T_SetOperationStmt:
-                               _outSetOperationStmt(str, obj);
-                               break;
                        case T_Plan:
                                _outPlan(str, obj);
                                break;
@@ -1437,18 +1413,6 @@ _outNode(StringInfo str, void *obj)
                        case T_Append:
                                _outAppend(str, obj);
                                break;
-                       case T_Join:
-                               _outJoin(str, obj);
-                               break;
-                       case T_NestLoop:
-                               _outNestLoop(str, obj);
-                               break;
-                       case T_MergeJoin:
-                               _outMergeJoin(str, obj);
-                               break;
-                       case T_HashJoin:
-                               _outHashJoin(str, obj);
-                               break;
                        case T_Scan:
                                _outScan(str, obj);
                                break;
@@ -1467,11 +1431,17 @@ _outNode(StringInfo str, void *obj)
                        case T_FunctionScan:
                                _outFunctionScan(str, obj);
                                break;
-                       case T_Material:
-                               _outMaterial(str, obj);
+                       case T_Join:
+                               _outJoin(str, obj);
                                break;
-                       case T_Sort:
-                               _outSort(str, obj);
+                       case T_NestLoop:
+                               _outNestLoop(str, obj);
+                               break;
+                       case T_MergeJoin:
+                               _outMergeJoin(str, obj);
+                               break;
+                       case T_HashJoin:
+                               _outHashJoin(str, obj);
                                break;
                        case T_Agg:
                                _outAgg(str, obj);
@@ -1479,6 +1449,12 @@ _outNode(StringInfo str, void *obj)
                        case T_Group:
                                _outGroup(str, obj);
                                break;
+                       case T_Material:
+                               _outMaterial(str, obj);
+                               break;
+                       case T_Sort:
+                               _outSort(str, obj);
+                               break;
                        case T_Unique:
                                _outUnique(str, obj);
                                break;
@@ -1491,14 +1467,14 @@ _outNode(StringInfo str, void *obj)
                        case T_Hash:
                                _outHash(str, obj);
                                break;
-                       case T_SubPlan:
-                               _outSubPlan(str, obj);
-                               break;
                        case T_Resdom:
                                _outResdom(str, obj);
                                break;
-                       case T_Expr:
-                               _outExpr(str, obj);
+                       case T_Alias:
+                               _outAlias(str, obj);
+                               break;
+                       case T_RangeVar:
+                               _outRangeVar(str, obj);
                                break;
                        case T_Var:
                                _outVar(str, obj);
@@ -1506,23 +1482,32 @@ _outNode(StringInfo str, void *obj)
                        case T_Const:
                                _outConst(str, obj);
                                break;
+                       case T_Param:
+                               _outParam(str, obj);
+                               break;
                        case T_Aggref:
                                _outAggref(str, obj);
                                break;
-                       case T_SubLink:
-                               _outSubLink(str, obj);
-                               break;
                        case T_ArrayRef:
                                _outArrayRef(str, obj);
                                break;
-                       case T_Func:
-                               _outFunc(str, obj);
+                       case T_FuncExpr:
+                               _outFuncExpr(str, obj);
                                break;
-                       case T_Oper:
-                               _outOper(str, obj);
+                       case T_OpExpr:
+                               _outOpExpr(str, obj);
                                break;
-                       case T_Param:
-                               _outParam(str, obj);
+                       case T_DistinctExpr:
+                               _outDistinctExpr(str, obj);
+                               break;
+                       case T_BoolExpr:
+                               _outBoolExpr(str, obj);
+                               break;
+                       case T_SubLink:
+                               _outSubLink(str, obj);
+                               break;
+                       case T_SubPlanExpr:
+                               _outSubPlanExpr(str, obj);
                                break;
                        case T_FieldSelect:
                                _outFieldSelect(str, obj);
@@ -1530,24 +1515,37 @@ _outNode(StringInfo str, void *obj)
                        case T_RelabelType:
                                _outRelabelType(str, obj);
                                break;
-                       case T_RangeTblRef:
-                               _outRangeTblRef(str, obj);
+                       case T_CaseExpr:
+                               _outCaseExpr(str, obj);
                                break;
-                       case T_FromExpr:
-                               _outFromExpr(str, obj);
+                       case T_CaseWhen:
+                               _outCaseWhen(str, obj);
                                break;
-                       case T_JoinExpr:
-                               _outJoinExpr(str, obj);
+                       case T_NullTest:
+                               _outNullTest(str, obj);
+                               break;
+                       case T_BooleanTest:
+                               _outBooleanTest(str, obj);
+                               break;
+                       case T_ConstraintTest:
+                               _outConstraintTest(str, obj);
+                               break;
+                       case T_ConstraintTestValue:
+                               _outConstraintTestValue(str, obj);
                                break;
                        case T_TargetEntry:
                                _outTargetEntry(str, obj);
                                break;
-                       case T_Alias:
-                               _outAlias(str, obj);
+                       case T_RangeTblRef:
+                               _outRangeTblRef(str, obj);
                                break;
-                       case T_RangeTblEntry:
-                               _outRangeTblEntry(str, obj);
+                       case T_JoinExpr:
+                               _outJoinExpr(str, obj);
+                               break;
+                       case T_FromExpr:
+                               _outFromExpr(str, obj);
                                break;
+
                        case T_Path:
                                _outPath(str, obj);
                                break;
@@ -1584,12 +1582,49 @@ _outNode(StringInfo str, void *obj)
                        case T_JoinInfo:
                                _outJoinInfo(str, obj);
                                break;
+
+                       case T_CreateStmt:
+                               _outCreateStmt(str, obj);
+                               break;
+                       case T_IndexStmt:
+                               _outIndexStmt(str, obj);
+                               break;
+                       case T_NotifyStmt:
+                               _outNotifyStmt(str, obj);
+                               break;
+                       case T_SelectStmt:
+                               _outSelectStmt(str, obj);
+                               break;
+                       case T_ColumnDef:
+                               _outColumnDef(str, obj);
+                               break;
+                       case T_TypeName:
+                               _outTypeName(str, obj);
+                               break;
+                       case T_TypeCast:
+                               _outTypeCast(str, obj);
+                               break;
+                       case T_IndexElem:
+                               _outIndexElem(str, obj);
+                               break;
+                       case T_Query:
+                               _outQuery(str, obj);
+                               break;
+                       case T_SortClause:
+                               _outSortClause(str, obj);
+                               break;
+                       case T_GroupClause:
+                               _outGroupClause(str, obj);
+                               break;
+                       case T_SetOperationStmt:
+                               _outSetOperationStmt(str, obj);
+                               break;
+                       case T_RangeTblEntry:
+                               _outRangeTblEntry(str, obj);
+                               break;
                        case T_A_Expr:
                                _outAExpr(str, obj);
                                break;
-                       case T_RangeVar:
-                               _outRangeVar(str, obj);
-                               break;
                        case T_ColumnRef:
                                _outColumnRef(str, obj);
                                break;
@@ -1602,36 +1637,18 @@ _outNode(StringInfo str, void *obj)
                        case T_ExprFieldSelect:
                                _outExprFieldSelect(str, obj);
                                break;
+                       case T_DomainConstraintValue:
+                               _outDomainConstraintValue(str, obj);
+                               break;
                        case T_Constraint:
                                _outConstraint(str, obj);
                                break;
                        case T_FkConstraint:
                                _outFkConstraint(str, obj);
                                break;
-                       case T_CaseExpr:
-                               _outCaseExpr(str, obj);
-                               break;
-                       case T_CaseWhen:
-                               _outCaseWhen(str, obj);
-                               break;
-                       case T_NullTest:
-                               _outNullTest(str, obj);
-                               break;
-                       case T_BooleanTest:
-                               _outBooleanTest(str, obj);
-                               break;
-                       case T_ConstraintTest:
-                               _outConstraintTest(str, obj);
-                               break;
-                       case T_ConstraintTestValue:
-                               _outConstraintTestValue(str, obj);
-                               break;
                        case T_FuncCall:
                                _outFuncCall(str, obj);
                                break;
-                       case T_DomainConstraintValue:
-                               _outDomainConstraintValue(str, obj);
-                               break;
 
                        default:
                                elog(WARNING, "_outNode: don't know how to print type %d",
index e8afda6..dd51868 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.57 2002/09/04 20:31:20 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.58 2002/12/12 15:49:28 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -371,7 +371,7 @@ print_expr(Node *expr, List *rtable)
                        char       *opname;
 
                        print_expr((Node *) get_leftop(e), rtable);
-                       opname = get_opname(((Oper *) e->oper)->opno);
+                       opname = get_opname(((OpExpr *) e)->opno);
                        printf(" %s ", ((opname != NULL) ? opname : "(invalid operator)"));
                        print_expr((Node *) get_rightop(e), rtable);
                }
@@ -432,7 +432,7 @@ print_tl(List *tlist, List *rtable)
                        printf("(%d):\t", tle->resdom->reskey);
                else
                        printf("    :\t");
-               print_expr(tle->expr, rtable);
+               print_expr((Node *) tle->expr, rtable);
                printf("\n");
        }
        printf(")\n");
index eca2e30..bb4a565 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.140 2002/11/25 21:29:38 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.141 2002/12/12 15:49:28 tgl Exp $
  *
  * NOTES
  *       Path and Plan nodes do not have any readfuncs support, because we
@@ -302,38 +302,30 @@ _readResdom(void)
        READ_DONE();
 }
 
-/*
- * _readExpr
- */
-static Expr *
-_readExpr(void)
+static Alias *
+_readAlias(void)
 {
-       READ_LOCALS(Expr);
+       READ_LOCALS(Alias);
 
-       READ_OID_FIELD(typeOid);
+       READ_STRING_FIELD(aliasname);
+       READ_NODE_FIELD(colnames);
 
-       /* do-it-yourself enum representation */
-       token = pg_strtok(&length); /* skip :opType */
-       token = pg_strtok(&length); /* get field value */
-       if (strncmp(token, "op", 2) == 0)
-               local_node->opType = OP_EXPR;
-       else if (strncmp(token, "distinct", 8) == 0)
-               local_node->opType = DISTINCT_EXPR;
-       else if (strncmp(token, "func", 4) == 0)
-               local_node->opType = FUNC_EXPR;
-       else if (strncmp(token, "or", 2) == 0)
-               local_node->opType = OR_EXPR;
-       else if (strncmp(token, "and", 3) == 0)
-               local_node->opType = AND_EXPR;
-       else if (strncmp(token, "not", 3) == 0)
-               local_node->opType = NOT_EXPR;
-       else if (strncmp(token, "subp", 4) == 0)
-               local_node->opType = SUBPLAN_EXPR;
-       else
-               elog(ERROR, "_readExpr: unknown opType \"%.*s\"", length, token);
+       READ_DONE();
+}
 
-       READ_NODE_FIELD(oper);
-       READ_NODE_FIELD(args);
+static RangeVar *
+_readRangeVar(void)
+{
+       READ_LOCALS(RangeVar);
+
+       local_node->catalogname = NULL;         /* not currently saved in output
+                                                                                * format */
+
+       READ_STRING_FIELD(schemaname);
+       READ_STRING_FIELD(relname);
+       READ_ENUM_FIELD(inhOpt, InhOption);
+       READ_BOOL_FIELD(istemp);
+       READ_NODE_FIELD(alias);
 
        READ_DONE();
 }
@@ -358,27 +350,6 @@ _readVar(void)
 }
 
 /*
- * _readArrayRef
- */
-static ArrayRef *
-_readArrayRef(void)
-{
-       READ_LOCALS(ArrayRef);
-
-       READ_OID_FIELD(refrestype);
-       READ_INT_FIELD(refattrlength);
-       READ_INT_FIELD(refelemlength);
-       READ_BOOL_FIELD(refelembyval);
-       READ_CHAR_FIELD(refelemalign);
-       READ_NODE_FIELD(refupperindexpr);
-       READ_NODE_FIELD(reflowerindexpr);
-       READ_NODE_FIELD(refexpr);
-       READ_NODE_FIELD(refassgnexpr);
-
-       READ_DONE();
-}
-
-/*
  * _readConst
  */
 static Const *
@@ -401,17 +372,72 @@ _readConst(void)
 }
 
 /*
- * _readFunc
+ * _readParam
+ */
+static Param *
+_readParam(void)
+{
+       READ_LOCALS(Param);
+
+       READ_INT_FIELD(paramkind);
+       READ_INT_FIELD(paramid);
+       READ_STRING_FIELD(paramname);
+       READ_OID_FIELD(paramtype);
+
+       READ_DONE();
+}
+
+/*
+ * _readAggref
+ */
+static Aggref *
+_readAggref(void)
+{
+       READ_LOCALS(Aggref);
+
+       READ_OID_FIELD(aggfnoid);
+       READ_OID_FIELD(aggtype);
+       READ_NODE_FIELD(target);
+       READ_BOOL_FIELD(aggstar);
+       READ_BOOL_FIELD(aggdistinct);
+
+       READ_DONE();
+}
+
+/*
+ * _readArrayRef
  */
-static Func *
-_readFunc(void)
+static ArrayRef *
+_readArrayRef(void)
 {
-       READ_LOCALS(Func);
+       READ_LOCALS(ArrayRef);
+
+       READ_OID_FIELD(refrestype);
+       READ_INT_FIELD(refattrlength);
+       READ_INT_FIELD(refelemlength);
+       READ_BOOL_FIELD(refelembyval);
+       READ_CHAR_FIELD(refelemalign);
+       READ_NODE_FIELD(refupperindexpr);
+       READ_NODE_FIELD(reflowerindexpr);
+       READ_NODE_FIELD(refexpr);
+       READ_NODE_FIELD(refassgnexpr);
+
+       READ_DONE();
+}
+
+/*
+ * _readFuncExpr
+ */
+static FuncExpr *
+_readFuncExpr(void)
+{
+       READ_LOCALS(FuncExpr);
 
        READ_OID_FIELD(funcid);
        READ_OID_FIELD(funcresulttype);
        READ_BOOL_FIELD(funcretset);
        READ_ENUM_FIELD(funcformat, CoercionForm);
+       READ_NODE_FIELD(args);
 
        local_node->func_fcache = NULL;
 
@@ -419,17 +445,28 @@ _readFunc(void)
 }
 
 /*
- * _readOper
+ * _readOpExpr
  */
-static Oper *
-_readOper(void)
+static OpExpr *
+_readOpExpr(void)
 {
-       READ_LOCALS(Oper);
+       READ_LOCALS(OpExpr);
 
        READ_OID_FIELD(opno);
-       READ_OID_FIELD(opid);
+       READ_OID_FIELD(opfuncid);
+       /*
+        * The opfuncid is stored in the textual format primarily for debugging
+        * and documentation reasons.  We want to always read it as zero to force
+        * it to be re-looked-up in the pg_operator entry.  This ensures that
+        * stored rules don't have hidden dependencies on operators' functions.
+        * (We don't currently support an ALTER OPERATOR command, but might
+        * someday.)
+        */
+       local_node->opfuncid = InvalidOid;
+
        READ_OID_FIELD(opresulttype);
        READ_BOOL_FIELD(opretset);
+       READ_NODE_FIELD(args);
 
        local_node->op_fcache = NULL;
 
@@ -437,52 +474,55 @@ _readOper(void)
 }
 
 /*
- * _readParam
+ * _readDistinctExpr
  */
-static Param *
-_readParam(void)
+static DistinctExpr *
+_readDistinctExpr(void)
 {
-       READ_LOCALS(Param);
-
-       READ_INT_FIELD(paramkind);
-       READ_INT_FIELD(paramid);
-       READ_STRING_FIELD(paramname);
-       READ_OID_FIELD(paramtype);
+       READ_LOCALS(DistinctExpr);
 
-       READ_DONE();
-}
+       READ_OID_FIELD(opno);
+       READ_OID_FIELD(opfuncid);
+       /*
+        * The opfuncid is stored in the textual format primarily for debugging
+        * and documentation reasons.  We want to always read it as zero to force
+        * it to be re-looked-up in the pg_operator entry.  This ensures that
+        * stored rules don't have hidden dependencies on operators' functions.
+        * (We don't currently support an ALTER OPERATOR command, but might
+        * someday.)
+        */
+       local_node->opfuncid = InvalidOid;
 
-/*
- * _readAggref
- */
-static Aggref *
-_readAggref(void)
-{
-       READ_LOCALS(Aggref);
+       READ_OID_FIELD(opresulttype);
+       READ_BOOL_FIELD(opretset);
+       READ_NODE_FIELD(args);
 
-       READ_OID_FIELD(aggfnoid);
-       READ_OID_FIELD(aggtype);
-       READ_NODE_FIELD(target);
-       READ_BOOL_FIELD(aggstar);
-       READ_BOOL_FIELD(aggdistinct);
-       /* aggno is not saved since it is just executor state */
+       local_node->op_fcache = NULL;
 
        READ_DONE();
 }
 
-static RangeVar *
-_readRangeVar(void)
+/*
+ * _readBoolExpr
+ */
+static BoolExpr *
+_readBoolExpr(void)
 {
-       READ_LOCALS(RangeVar);
+       READ_LOCALS(BoolExpr);
 
-       local_node->catalogname = NULL;         /* not currently saved in output
-                                                                                * format */
+       /* do-it-yourself enum representation */
+       token = pg_strtok(&length); /* skip :boolop */
+       token = pg_strtok(&length); /* get field value */
+       if (strncmp(token, "and", 3) == 0)
+               local_node->boolop = AND_EXPR;
+       else if (strncmp(token, "or", 2) == 0)
+               local_node->boolop = OR_EXPR;
+       else if (strncmp(token, "not", 3) == 0)
+               local_node->boolop = NOT_EXPR;
+       else
+               elog(ERROR, "_readBoolExpr: unknown boolop \"%.*s\"", length, token);
 
-       READ_STRING_FIELD(schemaname);
-       READ_STRING_FIELD(relname);
-       READ_ENUM_FIELD(inhOpt, InhOption);
-       READ_BOOL_FIELD(istemp);
-       READ_NODE_FIELD(alias);
+       READ_NODE_FIELD(args);
 
        READ_DONE();
 }
@@ -505,6 +545,10 @@ _readSubLink(void)
 }
 
 /*
+ * _readSubPlanExpr is not needed since it doesn't appear in stored rules.
+ */
+
+/*
  * _readFieldSelect
  */
 static FieldSelect *
@@ -537,58 +581,6 @@ _readRelabelType(void)
 }
 
 /*
- * _readRangeTblRef
- */
-static RangeTblRef *
-_readRangeTblRef(void)
-{
-       READ_LOCALS(RangeTblRef);
-
-       READ_INT_FIELD(rtindex);
-
-       READ_DONE();
-}
-
-/*
- * _readJoinExpr
- */
-static JoinExpr *
-_readJoinExpr(void)
-{
-       READ_LOCALS(JoinExpr);
-
-       READ_ENUM_FIELD(jointype, JoinType);
-       READ_BOOL_FIELD(isNatural);
-       READ_NODE_FIELD(larg);
-       READ_NODE_FIELD(rarg);
-       READ_NODE_FIELD(using);
-       READ_NODE_FIELD(quals);
-       READ_NODE_FIELD(alias);
-       READ_INT_FIELD(rtindex);
-
-       READ_DONE();
-}
-
-/*
- * _readFromExpr
- */
-static FromExpr *
-_readFromExpr(void)
-{
-       READ_LOCALS(FromExpr);
-
-       READ_NODE_FIELD(fromlist);
-       READ_NODE_FIELD(quals);
-
-       READ_DONE();
-}
-
-
-/*
- *     Stuff from parsenodes.h.
- */
-
-/*
  * _readCaseExpr
  */
 static CaseExpr *
@@ -664,17 +656,6 @@ _readConstraintTest(void)
 }
 
 /*
- * _readDomainConstraintValue
- */
-static DomainConstraintValue *
-_readDomainConstraintValue(void)
-{
-       READ_LOCALS_NO_FIELDS(DomainConstraintValue);
-
-       READ_DONE();
-}
-
-/*
  * _readConstraintTestValue
  */
 static ConstraintTestValue *
@@ -697,12 +678,63 @@ _readTargetEntry(void)
        READ_LOCALS(TargetEntry);
 
        READ_NODE_FIELD(resdom);
-       /* fjoin not supported ... */
        READ_NODE_FIELD(expr);
 
        READ_DONE();
 }
 
+/*
+ * _readRangeTblRef
+ */
+static RangeTblRef *
+_readRangeTblRef(void)
+{
+       READ_LOCALS(RangeTblRef);
+
+       READ_INT_FIELD(rtindex);
+
+       READ_DONE();
+}
+
+/*
+ * _readJoinExpr
+ */
+static JoinExpr *
+_readJoinExpr(void)
+{
+       READ_LOCALS(JoinExpr);
+
+       READ_ENUM_FIELD(jointype, JoinType);
+       READ_BOOL_FIELD(isNatural);
+       READ_NODE_FIELD(larg);
+       READ_NODE_FIELD(rarg);
+       READ_NODE_FIELD(using);
+       READ_NODE_FIELD(quals);
+       READ_NODE_FIELD(alias);
+       READ_INT_FIELD(rtindex);
+
+       READ_DONE();
+}
+
+/*
+ * _readFromExpr
+ */
+static FromExpr *
+_readFromExpr(void)
+{
+       READ_LOCALS(FromExpr);
+
+       READ_NODE_FIELD(fromlist);
+       READ_NODE_FIELD(quals);
+
+       READ_DONE();
+}
+
+
+/*
+ *     Stuff from parsenodes.h.
+ */
+
 static ColumnRef *
 _readColumnRef(void)
 {
@@ -760,13 +792,13 @@ _readExprFieldSelect(void)
        READ_DONE();
 }
 
-static Alias *
-_readAlias(void)
+/*
+ * _readDomainConstraintValue
+ */
+static DomainConstraintValue *
+_readDomainConstraintValue(void)
 {
-       READ_LOCALS(Alias);
-
-       READ_STRING_FIELD(aliasname);
-       READ_NODE_FIELD(colnames);
+       READ_LOCALS_NO_FIELDS(DomainConstraintValue);
 
        READ_DONE();
 }
@@ -835,53 +867,7 @@ parseNodeString(void)
 #define MATCH(tokname, namelen) \
        (length == namelen && strncmp(token, tokname, namelen) == 0)
 
-       if (MATCH("AGGREF", 6))
-               return_value = _readAggref();
-       else if (MATCH("SUBLINK", 7))
-               return_value = _readSubLink();
-       else if (MATCH("FIELDSELECT", 11))
-               return_value = _readFieldSelect();
-       else if (MATCH("RELABELTYPE", 11))
-               return_value = _readRelabelType();
-       else if (MATCH("RANGETBLREF", 11))
-               return_value = _readRangeTblRef();
-       else if (MATCH("FROMEXPR", 8))
-               return_value = _readFromExpr();
-       else if (MATCH("JOINEXPR", 8))
-               return_value = _readJoinExpr();
-       else if (MATCH("RESDOM", 6))
-               return_value = _readResdom();
-       else if (MATCH("EXPR", 4))
-               return_value = _readExpr();
-       else if (MATCH("ARRAYREF", 8))
-               return_value = _readArrayRef();
-       else if (MATCH("VAR", 3))
-               return_value = _readVar();
-       else if (MATCH("CONST", 5))
-               return_value = _readConst();
-       else if (MATCH("FUNC", 4))
-               return_value = _readFunc();
-       else if (MATCH("OPER", 4))
-               return_value = _readOper();
-       else if (MATCH("PARAM", 5))
-               return_value = _readParam();
-       else if (MATCH("TARGETENTRY", 11))
-               return_value = _readTargetEntry();
-       else if (MATCH("RANGEVAR", 8))
-               return_value = _readRangeVar();
-       else if (MATCH("COLUMNREF", 9))
-               return_value = _readColumnRef();
-       else if (MATCH("COLUMNDEF", 9))
-               return_value = _readColumnDef();
-       else if (MATCH("TYPENAME", 8))
-               return_value = _readTypeName();
-       else if (MATCH("EXPRFIELDSELECT", 15))
-               return_value = _readExprFieldSelect();
-       else if (MATCH("ALIAS", 5))
-               return_value = _readAlias();
-       else if (MATCH("RTE", 3))
-               return_value = _readRangeTblEntry();
-       else if (MATCH("QUERY", 5))
+       if (MATCH("QUERY", 5))
                return_value = _readQuery();
        else if (MATCH("NOTIFY", 6))
                return_value = _readNotifyStmt();
@@ -891,6 +877,36 @@ parseNodeString(void)
                return_value = _readGroupClause();
        else if (MATCH("SETOPERATIONSTMT", 16))
                return_value = _readSetOperationStmt();
+       else if (MATCH("RESDOM", 6))
+               return_value = _readResdom();
+       else if (MATCH("ALIAS", 5))
+               return_value = _readAlias();
+       else if (MATCH("RANGEVAR", 8))
+               return_value = _readRangeVar();
+       else if (MATCH("VAR", 3))
+               return_value = _readVar();
+       else if (MATCH("CONST", 5))
+               return_value = _readConst();
+       else if (MATCH("PARAM", 5))
+               return_value = _readParam();
+       else if (MATCH("AGGREF", 6))
+               return_value = _readAggref();
+       else if (MATCH("ARRAYREF", 8))
+               return_value = _readArrayRef();
+       else if (MATCH("FUNCEXPR", 8))
+               return_value = _readFuncExpr();
+       else if (MATCH("OPEXPR", 6))
+               return_value = _readOpExpr();
+       else if (MATCH("DISTINCTEXPR", 12))
+               return_value = _readDistinctExpr();
+       else if (MATCH("BOOLEXPR", 8))
+               return_value = _readBoolExpr();
+       else if (MATCH("SUBLINK", 7))
+               return_value = _readSubLink();
+       else if (MATCH("FIELDSELECT", 11))
+               return_value = _readFieldSelect();
+       else if (MATCH("RELABELTYPE", 11))
+               return_value = _readRelabelType();
        else if (MATCH("CASE", 4))
                return_value = _readCaseExpr();
        else if (MATCH("WHEN", 4))
@@ -901,10 +917,28 @@ parseNodeString(void)
                return_value = _readBooleanTest();
        else if (MATCH("CONSTRAINTTEST", 14))
                return_value = _readConstraintTest();
-       else if (MATCH("DOMAINCONSTRAINTVALUE", 21))
-               return_value = _readDomainConstraintValue();
        else if (MATCH("CONSTRAINTTESTVALUE", 19))
                return_value = _readConstraintTestValue();
+       else if (MATCH("TARGETENTRY", 11))
+               return_value = _readTargetEntry();
+       else if (MATCH("RANGETBLREF", 11))
+               return_value = _readRangeTblRef();
+       else if (MATCH("JOINEXPR", 8))
+               return_value = _readJoinExpr();
+       else if (MATCH("FROMEXPR", 8))
+               return_value = _readFromExpr();
+       else if (MATCH("COLUMNREF", 9))
+               return_value = _readColumnRef();
+       else if (MATCH("COLUMNDEF", 9))
+               return_value = _readColumnDef();
+       else if (MATCH("TYPENAME", 8))
+               return_value = _readTypeName();
+       else if (MATCH("EXPRFIELDSELECT", 15))
+               return_value = _readExprFieldSelect();
+       else if (MATCH("DOMAINCONSTRAINTVALUE", 21))
+               return_value = _readDomainConstraintValue();
+       else if (MATCH("RTE", 3))
+               return_value = _readRangeTblEntry();
        else
        {
                elog(ERROR, "badly formatted node string \"%.32s\"...", token);
index d0976ca..0294c82 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.53 2002/11/25 21:29:39 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.54 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -141,7 +141,7 @@ clauselist_selectivity(Query *root,
                if (is_opclause(clause) &&
                        (varRelid != 0 || NumRelids(clause) == 1))
                {
-                       Expr       *expr = (Expr *) clause;
+                       OpExpr     *expr = (OpExpr *) clause;
 
                        if (length(expr->args) == 2)
                        {
@@ -151,7 +151,7 @@ clauselist_selectivity(Query *root,
                                        (varonleft = false,
                                         is_pseudo_constant_clause(lfirst(expr->args))))
                                {
-                                       Oid                     opno = ((Oper *) expr->oper)->opno;
+                                       Oid                     opno = expr->opno;
                                        RegProcedure oprrest = get_oprrest(opno);
 
                                        s2 = restriction_selectivity(root, opno,
@@ -430,7 +430,7 @@ clause_selectivity(Query *root,
        {
                /* share code with clauselist_selectivity() */
                s1 = clauselist_selectivity(root,
-                                                                       ((Expr *) clause)->args,
+                                                                       ((BoolExpr *) clause)->args,
                                                                        varRelid);
        }
        else if (or_clause(clause))
@@ -443,7 +443,7 @@ clause_selectivity(Query *root,
                List       *arg;
 
                s1 = 0.0;
-               foreach(arg, ((Expr *) clause)->args)
+               foreach(arg, ((BoolExpr *) clause)->args)
                {
                        Selectivity s2 = clause_selectivity(root,
                                                                                                (Node *) lfirst(arg),
@@ -454,7 +454,7 @@ clause_selectivity(Query *root,
        }
        else if (is_opclause(clause))
        {
-               Oid                     opno = ((Oper *) ((Expr *) clause)->oper)->opno;
+               Oid                     opno = ((OpExpr *) clause)->opno;
                bool            is_join_clause;
 
                if (varRelid != 0)
@@ -479,13 +479,14 @@ clause_selectivity(Query *root,
                {
                        /* Estimate selectivity for a join clause. */
                        s1 = join_selectivity(root, opno,
-                                                                 ((Expr *) clause)->args);
+                                                                 ((OpExpr *) clause)->args);
                }
                else
                {
                        /* Estimate selectivity for a restriction clause. */
                        s1 = restriction_selectivity(root, opno,
-                                                                         ((Expr *) clause)->args, varRelid);
+                                                                                ((OpExpr *) clause)->args,
+                                                                                varRelid);
                }
        }
        else if (is_funcclause(clause))
@@ -509,7 +510,7 @@ clause_selectivity(Query *root,
                /* Use node specific selectivity calculation function */
                s1 = nulltestsel(root,
                                                 ((NullTest *) clause)->nulltesttype,
-                                                ((NullTest *) clause)->arg,
+                                                (Node *) ((NullTest *) clause)->arg,
                                                 varRelid);
        }
        else if (IsA(clause, BooleanTest))
@@ -517,14 +518,14 @@ clause_selectivity(Query *root,
                /* Use node specific selectivity calculation function */
                s1 = booltestsel(root,
                                                 ((BooleanTest *) clause)->booltesttype,
-                                                ((BooleanTest *) clause)->arg,
+                                                (Node *) ((BooleanTest *) clause)->arg,
                                                 varRelid);
        }
        else if (IsA(clause, RelabelType))
        {
                /* Not sure this case is needed, but it can't hurt */
                s1 = clause_selectivity(root,
-                                                               ((RelabelType *) clause)->arg,
+                                                               (Node *) ((RelabelType *) clause)->arg,
                                                                varRelid);
        }
 
index 1db310f..2125ff0 100644 (file)
@@ -42,7 +42,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.93 2002/11/30 05:21:02 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.94 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1220,63 +1220,48 @@ cost_qual_eval_walker(Node *node, Cost *total)
         * Should we try to account for the possibility of short-circuit
         * evaluation of AND/OR?
         */
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr) ||
+               IsA(node, OpExpr) ||
+               IsA(node, DistinctExpr))
+               *total += cpu_operator_cost;
+       else if (IsA(node, SubPlanExpr))
        {
-               Expr       *expr = (Expr *) node;
+               /*
+                * A subplan node in an expression indicates that the
+                * subplan will be executed on each evaluation, so charge
+                * accordingly. (We assume that sub-selects that can be
+                * executed as InitPlans have already been removed from
+                * the expression.)
+                *
+                * NOTE: this logic should agree with the estimates used by
+                * make_subplan() in plan/subselect.c.
+                */
+               SubPlanExpr *subplan = (SubPlanExpr *) node;
+               Plan       *plan = subplan->plan;
+               Cost            subcost;
 
-               switch (expr->opType)
+               if (subplan->sublink->subLinkType == EXISTS_SUBLINK)
                {
-                       case OP_EXPR:
-                       case DISTINCT_EXPR:
-                       case FUNC_EXPR:
-                               *total += cpu_operator_cost;
-                               break;
-                       case OR_EXPR:
-                       case AND_EXPR:
-                       case NOT_EXPR:
-                               break;
-                       case SUBPLAN_EXPR:
-
-                               /*
-                                * A subplan node in an expression indicates that the
-                                * subplan will be executed on each evaluation, so charge
-                                * accordingly. (We assume that sub-selects that can be
-                                * executed as InitPlans have already been removed from
-                                * the expression.)
-                                *
-                                * NOTE: this logic should agree with the estimates used by
-                                * make_subplan() in plan/subselect.c.
-                                */
-                               {
-                                       SubPlan    *subplan = (SubPlan *) expr->oper;
-                                       Plan       *plan = subplan->plan;
-                                       Cost            subcost;
-
-                                       if (subplan->sublink->subLinkType == EXISTS_SUBLINK)
-                                       {
-                                               /* we only need to fetch 1 tuple */
-                                               subcost = plan->startup_cost +
-                                                       (plan->total_cost - plan->startup_cost) / plan->plan_rows;
-                                       }
-                                       else if (subplan->sublink->subLinkType == ALL_SUBLINK ||
-                                                        subplan->sublink->subLinkType == ANY_SUBLINK)
-                                       {
-                                               /* assume we need 50% of the tuples */
-                                               subcost = plan->startup_cost +
-                                                       0.50 * (plan->total_cost - plan->startup_cost);
-                                               /* XXX what if subplan has been materialized? */
-                                       }
-                                       else
-                                       {
-                                               /* assume we need all tuples */
-                                               subcost = plan->total_cost;
-                                       }
-                                       *total += subcost;
-                               }
-                               break;
+                       /* we only need to fetch 1 tuple */
+                       subcost = plan->startup_cost +
+                               (plan->total_cost - plan->startup_cost) / plan->plan_rows;
                }
-               /* fall through to examine args of Expr node */
+               else if (subplan->sublink->subLinkType == ALL_SUBLINK ||
+                                subplan->sublink->subLinkType == ANY_SUBLINK)
+               {
+                       /* assume we need 50% of the tuples */
+                       subcost = plan->startup_cost +
+                               0.50 * (plan->total_cost - plan->startup_cost);
+                       /* XXX what if subplan has been materialized? */
+               }
+               else
+               {
+                       /* assume we need all tuples */
+                       subcost = plan->total_cost;
+               }
+               *total += subcost;
        }
+
        return expression_tree_walker(node, cost_qual_eval_walker,
                                                                  (void *) total);
 }
index c0241bb..7a20de8 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.126 2002/11/25 21:29:39 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.127 2002/12/12 15:49:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -73,6 +73,8 @@ static bool match_clause_to_indexkey(RelOptInfo *rel, IndexOptInfo *index,
                                                                         int indexkey, Oid opclass, Expr *clause);
 static bool match_join_clause_to_indexkey(RelOptInfo *rel, IndexOptInfo *index,
                                                 int indexkey, Oid opclass, Expr *clause);
+static Oid indexable_operator(Expr *clause, Oid opclass,
+                                  bool indexkey_on_left);
 static bool pred_test(List *predicate_list, List *restrictinfo_list,
                  List *joininfo_list, int relvarno);
 static bool pred_test_restrict_list(Expr *predicate, List *restrictinfo_list);
@@ -280,7 +282,7 @@ match_index_orclauses(RelOptInfo *rel,
                         */
                        restrictinfo->subclauseindices =
                                match_index_orclause(rel, index,
-                                                                        restrictinfo->clause->args,
+                                                                        ((BoolExpr *) restrictinfo->clause)->args,
                                                                         restrictinfo->subclauseindices);
                }
        }
@@ -377,7 +379,7 @@ match_or_subclause_to_indexkey(RelOptInfo *rel,
        {
                List       *item;
 
-               foreach(item, clause->args)
+               foreach(item, ((BoolExpr *) clause)->args)
                {
                        if (match_clause_to_indexkey(rel, index, indexkey, opclass,
                                                                                 lfirst(item)))
@@ -443,7 +445,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel,
 
                if (and_clause((Node *) orsubclause))
                {
-                       foreach(item, orsubclause->args)
+                       foreach(item, ((BoolExpr *) orsubclause)->args)
                        {
                                Expr       *subsubclause = (Expr *) lfirst(item);
 
@@ -715,7 +717,7 @@ match_clause_to_indexkey(RelOptInfo *rel,
                           *rightop;
 
        /* Clause must be a binary opclause. */
-       if (!is_opclause((Node *) clause))
+       if (!is_opclause(clause))
                return false;
        leftop = get_leftop(clause);
        rightop = get_rightop(clause);
@@ -803,7 +805,7 @@ match_join_clause_to_indexkey(RelOptInfo *rel,
                           *rightop;
 
        /* Clause must be a binary opclause. */
-       if (!is_opclause((Node *) clause))
+       if (!is_opclause(clause))
                return false;
        leftop = get_leftop(clause);
        rightop = get_rightop(clause);
@@ -857,10 +859,10 @@ match_join_clause_to_indexkey(RelOptInfo *rel,
  * (Formerly, this routine might return a binary-compatible operator
  * rather than the original one, but that kluge is history.)
  */
-Oid
+static Oid
 indexable_operator(Expr *clause, Oid opclass, bool indexkey_on_left)
 {
-       Oid                     expr_op = ((Oper *) clause->oper)->opno;
+       Oid                     expr_op = ((OpExpr *) clause)->opno;
        Oid                     commuted_op;
 
        /* Get the commuted operator if necessary */
@@ -985,7 +987,7 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
        Assert(clause != NULL);
        if (or_clause(clause))
        {
-               items = ((Expr *) clause)->args;
+               items = ((BoolExpr *) clause)->args;
                foreach(item, items)
                {
                        /* if any OR item doesn't imply the predicate, clause doesn't */
@@ -996,7 +998,7 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
        }
        else if (and_clause(clause))
        {
-               items = ((Expr *) clause)->args;
+               items = ((BoolExpr *) clause)->args;
                foreach(item, items)
                {
                        /*
@@ -1029,7 +1031,7 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
        Assert(predicate != NULL);
        if (or_clause((Node *) predicate))
        {
-               items = predicate->args;
+               items = ((BoolExpr *) predicate)->args;
                foreach(item, items)
                {
                        /* if any item is implied, the whole predicate is implied */
@@ -1040,7 +1042,7 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
        }
        else if (and_clause((Node *) predicate))
        {
-               items = predicate->args;
+               items = ((BoolExpr *) predicate)->args;
                foreach(item, items)
                {
                        /*
@@ -1121,7 +1123,6 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
        StrategyNumber pred_strategy = 0,
                                clause_strategy,
                                test_strategy;
-       Oper       *test_oper;
        Expr       *test_expr;
        Datum           test_result;
        bool            isNull;
@@ -1140,7 +1141,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
         * Can't do anything more unless they are both binary opclauses with a
         * Var on the left and a Const on the right.
         */
-       if (!is_opclause((Node *) predicate))
+       if (!is_opclause(predicate))
                return false;
        pred_var = (Var *) get_leftop(predicate);
        pred_const = (Const *) get_rightop(predicate);
@@ -1167,8 +1168,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
                return false;
 
        /* Get the operators for the two clauses we're comparing */
-       pred_op = ((Oper *) ((Expr *) predicate)->oper)->opno;
-       clause_op = ((Oper *) ((Expr *) clause)->oper)->opno;
+       pred_op = ((OpExpr *) predicate)->opno;
+       clause_op = ((OpExpr *) clause)->opno;
 
        /*
         * 1. Find a "btree" strategy number for the pred_op
@@ -1267,14 +1268,12 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
        /*
         * 5. Evaluate the test
         */
-       test_oper = makeOper(test_op,           /* opno */
-                                                InvalidOid,    /* opid */
-                                                BOOLOID,               /* opresulttype */
-                                                false);        /* opretset */
-       replace_opid(test_oper);
-       test_expr = make_opclause(test_oper,
-                                                         (Var *) clause_const,
-                                                         (Var *) pred_const);
+       test_expr = make_opclause(test_op,
+                                                         BOOLOID,
+                                                         false,
+                                                         (Expr *) clause_const,
+                                                         (Expr *) pred_const);
+       set_opfuncid((OpExpr *) test_expr);
 
        econtext = MakeExprContext(NULL, TransactionCommandContext);
        test_result = ExecEvalExprSwitchContext((Node *) test_expr, econtext,
@@ -1627,7 +1626,7 @@ static bool
 function_index_operand(Expr *funcOpnd, RelOptInfo *rel, IndexOptInfo *index)
 {
        int                     relvarno = lfirsti(rel->relids);
-       Func       *function;
+       FuncExpr   *function;
        List       *funcargs;
        int                *indexKeys = index->indexkeys;
        List       *arg;
@@ -1636,13 +1635,12 @@ function_index_operand(Expr *funcOpnd, RelOptInfo *rel, IndexOptInfo *index)
        /*
         * sanity check, make sure we know what we're dealing with here.
         */
-       if (funcOpnd == NULL || !IsA(funcOpnd, Expr) ||
-               funcOpnd->opType != FUNC_EXPR ||
-               funcOpnd->oper == NULL || indexKeys == NULL)
+       if (funcOpnd == NULL || !IsA(funcOpnd, FuncExpr) ||
+               indexKeys == NULL)
                return false;
 
-       function = (Func *) funcOpnd->oper;
-       funcargs = funcOpnd->args;
+       function = (FuncExpr *) funcOpnd;
+       funcargs = function->args;
 
        if (function->funcid != index->indproc)
                return false;
@@ -1752,7 +1750,7 @@ match_special_index_operator(Expr *clause, Oid opclass,
        /* we know these will succeed */
        leftop = get_leftop(clause);
        rightop = get_rightop(clause);
-       expr_op = ((Oper *) clause->oper)->opno;
+       expr_op = ((OpExpr *) clause)->opno;
 
        /* again, required for all current special ops: */
        if (!IsA(rightop, Const) ||
@@ -1916,7 +1914,7 @@ expand_indexqual_conditions(List *indexquals)
                /* we know these will succeed */
                Var                *leftop = get_leftop(clause);
                Var                *rightop = get_rightop(clause);
-               Oid                     expr_op = ((Oper *) clause->oper)->opno;
+               Oid                     expr_op = ((OpExpr *) clause)->opno;
                Const      *patt = (Const *) rightop;
                Const      *prefix = NULL;
                Const      *rest = NULL;
@@ -2011,7 +2009,6 @@ prefix_quals(Var *leftop, Oid expr_op,
        Oid                     oproid;
        char       *prefix;
        Const      *con;
-       Oper       *op;
        Expr       *expr;
        Const      *greaterstr = NULL;
 
@@ -2070,8 +2067,8 @@ prefix_quals(Var *leftop, Oid expr_op,
                if (oproid == InvalidOid)
                        elog(ERROR, "prefix_quals: no = operator for type %u", datatype);
                con = string_to_const(prefix, datatype);
-               op = makeOper(oproid, InvalidOid, BOOLOID, false);
-               expr = make_opclause(op, leftop, (Var *) con);
+               expr = make_opclause(oproid, BOOLOID, false,
+                                                        (Expr *) leftop, (Expr *) con);
                result = makeList1(expr);
                return result;
        }
@@ -2085,8 +2082,8 @@ prefix_quals(Var *leftop, Oid expr_op,
        if (oproid == InvalidOid)
                elog(ERROR, "prefix_quals: no >= operator for type %u", datatype);
        con = string_to_const(prefix, datatype);
-       op = makeOper(oproid, InvalidOid, BOOLOID, false);
-       expr = make_opclause(op, leftop, (Var *) con);
+       expr = make_opclause(oproid, BOOLOID, false,
+                                                (Expr *) leftop, (Expr *) con);
        result = makeList1(expr);
 
        /*-------
@@ -2100,8 +2097,8 @@ prefix_quals(Var *leftop, Oid expr_op,
                oproid = find_operator("<", datatype);
                if (oproid == InvalidOid)
                        elog(ERROR, "prefix_quals: no < operator for type %u", datatype);
-               op = makeOper(oproid, InvalidOid, BOOLOID, false);
-               expr = make_opclause(op, leftop, (Var *) greaterstr);
+               expr = make_opclause(oproid, BOOLOID, false,
+                                                        (Expr *) leftop, (Expr *) greaterstr);
                result = lappend(result, expr);
        }
 
@@ -2124,7 +2121,6 @@ network_prefix_quals(Var *leftop, Oid expr_op, Datum rightop)
        Oid                     opr2oid;
        List       *result;
        Oid                     datatype;
-       Oper       *op;
        Expr       *expr;
 
        switch (expr_op)
@@ -2164,10 +2160,10 @@ network_prefix_quals(Var *leftop, Oid expr_op, Datum rightop)
 
        opr1right = network_scan_first(rightop);
 
-       op = makeOper(opr1oid, InvalidOid, BOOLOID, false);
-       expr = make_opclause(op, leftop,
-                                                (Var *) makeConst(datatype, -1, opr1right,
-                                                                                  false, false));
+       expr = make_opclause(opr1oid, BOOLOID, false,
+                                                (Expr *) leftop,
+                                                (Expr *) makeConst(datatype, -1, opr1right,
+                                                                                       false, false));
        result = makeList1(expr);
 
        /* create clause "key <= network_scan_last( rightop )" */
@@ -2179,10 +2175,10 @@ network_prefix_quals(Var *leftop, Oid expr_op, Datum rightop)
 
        opr2right = network_scan_last(rightop);
 
-       op = makeOper(opr2oid, InvalidOid, BOOLOID, false);
-       expr = make_opclause(op, leftop,
-                                                (Var *) makeConst(datatype, -1, opr2right,
-                                                                                  false, false));
+       expr = make_opclause(opr2oid, BOOLOID, false,
+                                                (Expr *) leftop,
+                                                (Expr *) makeConst(datatype, -1, opr2right,
+                                                                                       false, false));
        result = lappend(result, expr);
 
        return result;
index 009afdf..1018668 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.48 2002/11/24 21:52:14 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.49 2002/12/12 15:49:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -96,7 +96,7 @@ create_or_index_paths(Query *root, RelOptInfo *rel)
 
                                best_or_subclause_indices(root,
                                                                                  rel,
-                                                                                 restrictinfo->clause->args,
+                                                                                 ((BoolExpr *) restrictinfo->clause)->args,
                                                                                  restrictinfo->subclauseindices,
                                                                                  pathnode);
 
index 350c761..af0b61a 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.41 2002/09/18 21:35:21 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.42 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -514,14 +514,16 @@ build_index_pathkeys(Query *root,
        if (index->indproc)
        {
                /* Functional index: build a representation of the function call */
-               Func       *funcnode = makeNode(Func);
+               Expr       *funcnode;
                List       *funcargs = NIL;
 
-               funcnode->funcid = index->indproc;
-               funcnode->funcresulttype = get_func_rettype(index->indproc);
-               funcnode->funcretset = false;   /* can never be a set */
-               funcnode->funcformat = COERCE_DONTCARE; /* to match any user expr */
-               funcnode->func_fcache = NULL;
+               sortop = *ordering;
+               if (ScanDirectionIsBackward(scandir))
+               {
+                       sortop = get_commutator(sortop);
+                       if (sortop == InvalidOid)
+                               return NIL;             /* oops, no reverse sort operator? */
+               }
 
                while (*indexkeys != 0)
                {
@@ -530,17 +532,14 @@ build_index_pathkeys(Query *root,
                        indexkeys++;
                }
 
-               sortop = *ordering;
-               if (ScanDirectionIsBackward(scandir))
-               {
-                       sortop = get_commutator(sortop);
-                       if (sortop == InvalidOid)
-                               return NIL;             /* oops, no reverse sort operator? */
-               }
+               funcnode = make_funcclause(index->indproc,
+                                                                  get_func_rettype(index->indproc),
+                                                                  false, /* cannot be a set */
+                                                                  COERCE_DONTCARE,     /* to match any user expr */
+                                                                  funcargs);
 
                /* Make a one-sublist pathkeys list for the function expression */
-               item = makePathKeyItem((Node *) make_funcclause(funcnode, funcargs),
-                                                          sortop);
+               item = makePathKeyItem((Node *) funcnode, sortop);
                retval = makeList1(make_canonical_pathkey(root, item));
        }
        else
index 27fe9e2..f11ff81 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.12 2002/11/24 21:52:14 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/tidpath.c,v 1.13 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 static List *TidqualFromRestrictinfo(List *relids, List *restrictinfo);
 static bool isEvaluable(int varno, Node *node);
-static Node *TidequalClause(int varno, Expr *node);
+static Node *TidequalClause(int varno, OpExpr *node);
 static List *TidqualFromExpr(int varno, Expr *expr);
 
-static
-bool
+static bool
 isEvaluable(int varno, Node *node)
 {
        List       *lst;
-       Expr       *expr;
+       FuncExpr   *expr;
 
        if (IsA(node, Const))
                return true;
@@ -51,7 +50,7 @@ isEvaluable(int varno, Node *node)
        }
        if (!is_funcclause(node))
                return false;
-       expr = (Expr *) node;
+       expr = (FuncExpr *) node;
        foreach(lst, expr->args)
        {
                if (!isEvaluable(varno, lfirst(lst)))
@@ -66,33 +65,26 @@ isEvaluable(int varno, Node *node)
  *     Extract the right node if the opclause is CTID= ....
  *       or    the left  node if the opclause is ....=CTID
  */
-static
-Node *
-TidequalClause(int varno, Expr *node)
+static Node *
+TidequalClause(int varno, OpExpr *node)
 {
-       Node       *rnode = 0,
+       Node       *rnode = NULL,
                           *arg1,
                           *arg2,
                           *arg;
-       Oper       *oper;
        Var                *var;
        Const      *aconst;
        Param      *param;
-       Expr       *expr;
+       FuncExpr   *expr;
 
-       if (!node->oper)
-               return rnode;
-       if (!node->args)
+       if (node->opno != TIDEqualOperator)
                return rnode;
        if (length(node->args) != 2)
                return rnode;
-       oper = (Oper *) node->oper;
-       if (oper->opno != TIDEqualOperator)
-               return rnode;
        arg1 = lfirst(node->args);
        arg2 = lsecond(node->args);
 
-       arg = (Node *) 0;
+       arg = NULL;
        if (IsA(arg1, Var))
        {
                var = (Var *) arg1;
@@ -138,11 +130,9 @@ TidequalClause(int varno, Expr *node)
                                return rnode;
                        rnode = arg;
                        break;
-               case T_Expr:
-                       expr = (Expr *) arg;
-                       if (expr->typeOid != TIDOID)
-                               return rnode;
-                       if (expr->opType != FUNC_EXPR)
+               case T_FuncExpr:
+                       expr = (FuncExpr *) arg;
+                       if (expr->funcresulttype != TIDOID)
                                return rnode;
                        if (isEvaluable(varno, (Node *) expr))
                                rnode = arg;
@@ -162,8 +152,7 @@ TidequalClause(int varno, Expr *node)
  *     CTID values if we could extract the CTID values from a member
  *     node.
  */
-static
-List *
+static List *
 TidqualFromExpr(int varno, Expr *expr)
 {
        List       *rlst = NIL,
@@ -174,17 +163,15 @@ TidqualFromExpr(int varno, Expr *expr)
 
        if (is_opclause(node))
        {
-               rnode = TidequalClause(varno, expr);
+               rnode = TidequalClause(varno, (OpExpr *) expr);
                if (rnode)
                        rlst = lcons(rnode, rlst);
        }
        else if (and_clause(node))
        {
-               foreach(lst, expr->args)
+               foreach(lst, ((BoolExpr *) expr)->args)
                {
                        node = lfirst(lst);
-                       if (!IsA(node, Expr))
-                               continue;
                        rlst = TidqualFromExpr(varno, (Expr *) node);
                        if (rlst)
                                break;
@@ -192,11 +179,11 @@ TidqualFromExpr(int varno, Expr *expr)
        }
        else if (or_clause(node))
        {
-               foreach(lst, expr->args)
+               foreach(lst, ((BoolExpr *) expr)->args)
                {
                        node = lfirst(lst);
-                       if (IsA(node, Expr) &&
-                               (frtn = TidqualFromExpr(varno, (Expr *) node)))
+                       frtn = TidqualFromExpr(varno, (Expr *) node);
+                       if (frtn)
                                rlst = nconc(rlst, frtn);
                        else
                        {
index 0414fdf..a67e23f 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.127 2002/12/05 15:50:35 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.128 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1041,12 +1041,12 @@ fix_indxqual_sublist(List *indexqual, int baserelid, IndexOptInfo *index,
 
        foreach(i, indexqual)
        {
-               Expr       *clause = (Expr *) lfirst(i);
-               Expr       *newclause;
+               OpExpr     *clause = (OpExpr *) lfirst(i);
+               OpExpr     *newclause;
                List       *leftvarnos;
                Oid                     opclass;
 
-               if (!is_opclause((Node *) clause) || length(clause->args) != 2)
+               if (!IsA(clause, OpExpr) || length(clause->args) != 2)
                        elog(ERROR, "fix_indxqual_sublist: indexqual clause is not binary opclause");
 
                /*
@@ -1056,7 +1056,7 @@ fix_indxqual_sublist(List *indexqual, int baserelid, IndexOptInfo *index,
                 * is a subplan in the arguments of the opclause.  So just do a
                 * full copy.
                 */
-               newclause = (Expr *) copyObject((Node *) clause);
+               newclause = (OpExpr *) copyObject((Node *) clause);
 
                /*
                 * Check to see if the indexkey is on the right; if so, commute
@@ -1083,7 +1083,7 @@ fix_indxqual_sublist(List *indexqual, int baserelid, IndexOptInfo *index,
                 * Finally, check to see if index is lossy for this operator. If
                 * so, add (a copy of) original form of clause to recheck list.
                 */
-               if (op_requires_recheck(((Oper *) newclause->oper)->opno, opclass))
+               if (op_requires_recheck(newclause->opno, opclass))
                        recheck_qual = lappend(recheck_qual,
                                                                   copyObject((Node *) clause));
        }
@@ -1100,7 +1100,7 @@ fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
         * Remove any binary-compatible relabeling of the indexkey
         */
        if (IsA(node, RelabelType))
-               node = ((RelabelType *) node)->arg;
+               node = (Node *) ((RelabelType *) node)->arg;
 
        /*
         * We represent index keys by Var nodes having the varno of the base
@@ -1168,11 +1168,11 @@ switch_outer(List *clauses)
 
        foreach(i, clauses)
        {
-               Expr       *clause = (Expr *) lfirst(i);
+               OpExpr     *clause = (OpExpr *) lfirst(i);
                Var                *op;
 
-               Assert(is_opclause((Node *) clause));
-               op = get_rightop(clause);
+               Assert(is_opclause(clause));
+               op = get_rightop((Expr *) clause);
                Assert(op && IsA(op, Var));
                if (var_is_outer(op))
                {
@@ -1181,10 +1181,13 @@ switch_outer(List *clauses)
                         * the clause without changing the original list.  Could use
                         * copyObject, but a complete deep copy is overkill.
                         */
-                       Expr       *temp;
+                       OpExpr     *temp = makeNode(OpExpr);
 
-                       temp = make_clause(clause->opType, clause->oper,
-                                                          listCopy(clause->args));
+                       temp->opno = clause->opno;
+                       temp->opfuncid = InvalidOid;
+                       temp->opresulttype = clause->opresulttype;
+                       temp->opretset = clause->opretset;
+                       temp->args = listCopy(clause->args);
                        /* Commute it --- note this modifies the temp node in-place. */
                        CommuteClause(temp);
                        t_list = lappend(t_list, temp);
index 529ba71..aca2c6f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.77 2002/11/24 21:52:14 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.78 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -761,14 +761,11 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
                elog(ERROR, "Equality operator for types '%s' and '%s' should be mergejoinable, but isn't",
                         format_type_be(ltype), format_type_be(rtype));
 
-       clause = makeNode(Expr);
-       clause->typeOid = BOOLOID;
-       clause->opType = OP_EXPR;
-       clause->oper = (Node *) makeOper(oprid(eq_operator),            /* opno */
-                                                                        InvalidOid,            /* opid */
-                                                                        BOOLOID,       /* opresulttype */
-                                                                        false);        /* opretset */
-       clause->args = makeList2(item1, item2);
+       clause = make_opclause(oprid(eq_operator), /* opno */
+                                                  BOOLOID,     /* opresulttype */
+                                                  false, /* opretset */
+                                                  (Expr *) item1,
+                                                  (Expr *) item2);
 
        ReleaseSysCache(eq_operator);
 
@@ -969,7 +966,7 @@ check_mergejoinable(RestrictInfo *restrictinfo)
                                leftOp,
                                rightOp;
 
-       if (!is_opclause((Node *) clause))
+       if (!is_opclause(clause))
                return;
 
        left = get_leftop(clause);
@@ -978,10 +975,11 @@ check_mergejoinable(RestrictInfo *restrictinfo)
        /* caution: is_opclause accepts more than I do, so check it */
        if (!right)
                return;                                 /* unary opclauses need not apply */
-       if (!IsA(left, Var) ||!IsA(right, Var))
+       if (!IsA(left, Var) ||
+               !IsA(right, Var))
                return;
 
-       opno = ((Oper *) clause->oper)->opno;
+       opno = ((OpExpr *) clause)->opno;
 
        if (op_mergejoinable(opno,
                                                 left->vartype,
@@ -1012,7 +1010,7 @@ check_hashjoinable(RestrictInfo *restrictinfo)
                           *right;
        Oid                     opno;
 
-       if (!is_opclause((Node *) clause))
+       if (!is_opclause(clause))
                return;
 
        left = get_leftop(clause);
@@ -1021,10 +1019,11 @@ check_hashjoinable(RestrictInfo *restrictinfo)
        /* caution: is_opclause accepts more than I do, so check it */
        if (!right)
                return;                                 /* unary opclauses need not apply */
-       if (!IsA(left, Var) ||!IsA(right, Var))
+       if (!IsA(left, Var) ||
+               !IsA(right, Var))
                return;
 
-       opno = ((Oper *) clause->oper)->opno;
+       opno = ((OpExpr *) clause)->opno;
 
        if (op_hashjoinable(opno,
                                                left->vartype,
index ebb9f3d..b3d7b53 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.133 2002/12/05 21:46:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.134 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -91,7 +91,7 @@ planner(Query *parse)
         * purpose is communication across multiple sub-Queries.
         *
         * Note we do NOT save and restore PlannerPlanId: it exists to assign
-        * unique IDs to SubPlan nodes, and we want those IDs to be unique for
+        * unique IDs to SubPlanExpr nodes, and we want those IDs to be unique for
         * the life of a backend.  Also, PlannerInitPlan is saved/restored in
         * subquery_planner, not here.
         */
@@ -278,7 +278,7 @@ subquery_planner(Query *parse, double tuple_fraction)
                /* Must add the initPlans' extParams to the topmost node's, too */
                foreach(lst, plan->initPlan)
                {
-                       SubPlan    *subplan = (SubPlan *) lfirst(lst);
+                       SubPlanExpr *subplan = (SubPlanExpr *) lfirst(lst);
 
                        plan->extParam = set_unioni(plan->extParam,
                                                                                subplan->plan->extParam);
@@ -1015,7 +1015,7 @@ grouping_planner(Query *parse, double tuple_fraction)
                                                          -1,
                                                          0);
 
-                               ctid = makeTargetEntry(resdom, (Node *) var);
+                               ctid = makeTargetEntry(resdom, (Expr *) var);
                                tlist = lappend(tlist, ctid);
                        }
                }
@@ -1707,7 +1707,7 @@ make_subplanTargetList(Query *parse,
                                                                                                exprTypmod(groupexpr),
                                                                                                NULL,
                                                                                                false),
-                                                                        groupexpr);
+                                                                        (Expr *) groupexpr);
                                sub_tlist = lappend(sub_tlist, te);
                        }
 
index b23843a..0d66c97 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.84 2002/12/05 15:50:35 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.85 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -52,7 +52,7 @@ static Node *replace_vars_with_subplan_refs(Node *node,
                                                           bool tlist_has_non_vars);
 static Node *replace_vars_with_subplan_refs_mutator(Node *node,
                                                replace_vars_with_subplan_refs_context *context);
-static bool fix_opids_walker(Node *node, void *context);
+static bool fix_opfuncids_walker(Node *node, void *context);
 
 /*****************************************************************************
  *
@@ -219,7 +219,7 @@ set_plan_references(Plan *plan, List *rtable)
         * subplan references in this plan's tlist and quals.  If we did the
         * reference-adjustments bottom-up, then we would fail to match this
         * plan's var nodes against the already-modified nodes of the
-        * children.  Fortunately, that consideration doesn't apply to SubPlan
+        * children.  Fortunately, that consideration doesn't apply to SubPlanExpr
         * nodes; else we'd need two passes over the expression trees.
         */
        set_plan_references(plan->lefttree, rtable);
@@ -227,9 +227,9 @@ set_plan_references(Plan *plan, List *rtable)
 
        foreach(pl, plan->initPlan)
        {
-               SubPlan    *sp = (SubPlan *) lfirst(pl);
+               SubPlanExpr *sp = (SubPlanExpr *) lfirst(pl);
 
-               Assert(IsA(sp, SubPlan));
+               Assert(IsA(sp, SubPlanExpr));
                set_plan_references(sp->plan, sp->rtable);
        }
 }
@@ -238,8 +238,8 @@ set_plan_references(Plan *plan, List *rtable)
  * fix_expr_references
  *       Do final cleanup on expressions (targetlists or quals).
  *
- * This consists of looking up operator opcode info for Oper nodes
- * and recursively performing set_plan_references on SubPlans.
+ * This consists of looking up operator opcode info for OpExpr nodes
+ * and recursively performing set_plan_references on subplans.
  *
  * The Plan argument is currently unused, but might be needed again someday.
  */
@@ -255,20 +255,15 @@ fix_expr_references_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (IsA(node, Expr))
+       if (IsA(node, OpExpr))
+               set_opfuncid((OpExpr *) node);
+       else if (IsA(node, DistinctExpr))
+               set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
+       else if (IsA(node, SubPlanExpr))
        {
-               Expr   *expr = (Expr *) node;
+               SubPlanExpr *sp = (SubPlanExpr *) node;
 
-               if (expr->opType == OP_EXPR ||
-                       expr->opType == DISTINCT_EXPR)
-                       replace_opid((Oper *) expr->oper);
-               else if (expr->opType == SUBPLAN_EXPR)
-               {
-                       SubPlan    *sp = (SubPlan *) expr->oper;
-
-                       Assert(IsA(sp, SubPlan));
-                       set_plan_references(sp->plan, sp->rtable);
-               }
+               set_plan_references(sp->plan, sp->rtable);
        }
        return expression_tree_walker(node, fix_expr_references_walker, context);
 }
@@ -362,12 +357,13 @@ set_uppernode_references(Plan *plan, Index subvarno)
                TargetEntry *tle = (TargetEntry *) lfirst(l);
                Node       *newexpr;
 
-               newexpr = replace_vars_with_subplan_refs(tle->expr,
+               newexpr = replace_vars_with_subplan_refs((Node *) tle->expr,
                                                                                                 subvarno,
                                                                                                 subplan_targetlist,
                                                                                                 tlist_has_non_vars);
                output_targetlist = lappend(output_targetlist,
-                                                                 makeTargetEntry(tle->resdom, newexpr));
+                                                                 makeTargetEntry(tle->resdom,
+                                                                                                 (Expr *) newexpr));
        }
        plan->targetlist = output_targetlist;
 
@@ -570,8 +566,8 @@ replace_vars_with_subplan_refs_mutator(Node *node,
  *****************************************************************************/
 
 /*
- * fix_opids
- *       Calculate opid field from opno for each Oper node in given tree.
+ * fix_opfuncids
+ *       Calculate opfuncid field from opno for each OpExpr node in given tree.
  *       The given tree can be anything expression_tree_walker handles.
  *
  * The argument is modified in-place.  (This is OK since we'd want the
@@ -579,24 +575,20 @@ replace_vars_with_subplan_refs_mutator(Node *node,
  * shared structure.)
  */
 void
-fix_opids(Node *node)
+fix_opfuncids(Node *node)
 {
        /* This tree walk requires no special setup, so away we go... */
-       fix_opids_walker(node, NULL);
+       fix_opfuncids_walker(node, NULL);
 }
 
 static bool
-fix_opids_walker(Node *node, void *context)
+fix_opfuncids_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (IsA(node, Expr))
-       {
-               Expr   *expr = (Expr *) node;
-
-               if (expr->opType == OP_EXPR ||
-                       expr->opType == DISTINCT_EXPR)
-                       replace_opid((Oper *) expr->oper);
-       }
-       return expression_tree_walker(node, fix_opids_walker, context);
+       if (IsA(node, OpExpr))
+               set_opfuncid((OpExpr *) node);
+       else if (IsA(node, DistinctExpr))
+               set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
+       return expression_tree_walker(node, fix_opfuncids_walker, context);
 }
index a65de72..fe17b8e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.59 2002/12/05 15:50:35 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.60 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -144,12 +144,12 @@ generate_new_param(Oid paramtype, int32 paramtypmod)
 }
 
 /*
- * Convert a bare SubLink (as created by the parser) into a SubPlan.
+ * Convert a bare SubLink (as created by the parser) into a SubPlanExpr.
  */
 static Node *
 make_subplan(SubLink *slink)
 {
-       SubPlan    *node = makeNode(SubPlan);
+       SubPlanExpr *node = makeNode(SubPlanExpr);
        Query      *subquery = (Query *) (slink->subselect);
        Oid                     result_type = exprType((Node *) slink);
        double          tuple_fraction;
@@ -210,11 +210,13 @@ make_subplan(SubLink *slink)
        node->plan = plan = subquery_planner(subquery, tuple_fraction);
 
        node->plan_id = PlannerPlanId++;        /* Assign unique ID to this
-                                                                                * SubPlan */
+                                                                                * SubPlanExpr */
 
        node->rtable = subquery->rtable;
        node->sublink = slink;
 
+       node->typeOid = result_type;
+
        slink->subselect = NULL;        /* cool ?! see error check above! */
 
        /*
@@ -270,7 +272,6 @@ make_subplan(SubLink *slink)
        }
        else
        {
-               Expr       *expr = makeNode(Expr);
                List       *args = NIL;
 
                /*
@@ -350,14 +351,7 @@ make_subplan(SubLink *slink)
                convert_sublink_opers(slink, plan->targetlist, NULL);
 
                /*
-                * Make expression of SUBPLAN type
-                */
-               expr->typeOid = result_type;
-               expr->opType = SUBPLAN_EXPR;
-               expr->oper = (Node *) node;
-
-               /*
-                * Make expr->args from parParam.
+                * Make node->args from parParam.
                 */
                foreach(lst, node->parParam)
                {
@@ -373,9 +367,9 @@ make_subplan(SubLink *slink)
                        var->varlevelsup = 0;
                        args = lappend(args, var);
                }
-               expr->args = args;
+               node->args = args;
 
-               result = (Node *) expr;
+               result = (Node *) node;
        }
 
        return result;
@@ -385,7 +379,7 @@ make_subplan(SubLink *slink)
  * convert_sublink_opers: convert a SubLink's oper list from the
  * parser/rewriter format into the executor's format.
  *
- * The oper list is initially just a list of Oper nodes.  We replace it
+ * The oper list is initially just a list of OpExpr nodes.  We replace it
  * with a list of actually executable expressions, in which the specified
  * operators are applied to corresponding elements of the lefthand list
  * and Params representing the results of the subplan.  lefthand is then
@@ -404,7 +398,7 @@ convert_sublink_opers(SubLink *slink, List *targetlist,
 
        foreach(lst, slink->oper)
        {
-               Oper       *oper = (Oper *) lfirst(lst);
+               OpExpr     *oper = (OpExpr *) lfirst(lst);
                Node       *lefthand = lfirst(leftlist);
                TargetEntry *te = lfirst(targetlist);
                Param      *prm;
@@ -422,7 +416,7 @@ convert_sublink_opers(SubLink *slink, List *targetlist,
                        *setParams = lappendi(*setParams, prm->paramid);
 
                /* Look up the operator to check its declared input types */
-               Assert(IsA(oper, Oper));
+               Assert(IsA(oper, OpExpr));
                tup = SearchSysCache(OPEROID,
                                                         ObjectIdGetDatum(oper->opno),
                                                         0, 0, 0);
@@ -439,9 +433,11 @@ convert_sublink_opers(SubLink *slink, List *targetlist,
                left = make_operand(lefthand, exprType(lefthand), opform->oprleft);
                right = make_operand((Node *) prm, prm->paramtype, opform->oprright);
                newoper = lappend(newoper,
-                                                 make_opclause(oper,
-                                                                               (Var *) left,
-                                                                               (Var *) right));
+                                                 make_opclause(oper->opno,
+                                                                               oper->opresulttype,
+                                                                               oper->opretset,
+                                                                               (Expr *) left,
+                                                                               (Expr *) right));
 
                ReleaseSysCache(tup);
 
@@ -482,7 +478,7 @@ finalize_primnode(Node *node, finalize_primnode_results *results)
        }
        if (is_subplan(node))
        {
-               SubPlan    *subplan = (SubPlan *) ((Expr *) node)->oper;
+               SubPlanExpr *subplan = (SubPlanExpr *) node;
                List       *lst;
 
                /* Check extParam list for params to add to paramids */
@@ -559,12 +555,12 @@ process_sublinks_mutator(Node *node, void *context)
                 */
                sublink->lefthand = (List *)
                        process_sublinks_mutator((Node *) sublink->lefthand, context);
-               /* Now build the SubPlan node and make the expr to return */
+               /* Now build the SubPlanExpr node and make the expr to return */
                return make_subplan(sublink);
        }
 
        /*
-        * Note that we will never see a SubPlan expression in the input
+        * Note that we will never see a SubPlanExpr expression in the input
         * (since this is the very routine that creates 'em to begin with). So
         * the code in expression_tree_mutator() that might do inappropriate
         * things with SubPlans or SubLinks will not be exercised.
index bb00555..4016ba4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.33 2002/09/02 02:47:02 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepqual.c,v 1.34 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -294,7 +294,7 @@ flatten_andors(Expr *qual)
                List       *out_list = NIL;
                List       *arg;
 
-               foreach(arg, qual->args)
+               foreach(arg, ((BoolExpr *) qual)->args)
                {
                        Expr       *subexpr = flatten_andors((Expr *) lfirst(arg));
 
@@ -305,7 +305,7 @@ flatten_andors(Expr *qual)
                         * with any other expr. Otherwise we'd need a listCopy here.
                         */
                        if (and_clause((Node *) subexpr))
-                               out_list = nconc(out_list, subexpr->args);
+                               out_list = nconc(out_list, ((BoolExpr *) subexpr)->args);
                        else
                                out_list = lappend(out_list, subexpr);
                }
@@ -316,7 +316,7 @@ flatten_andors(Expr *qual)
                List       *out_list = NIL;
                List       *arg;
 
-               foreach(arg, qual->args)
+               foreach(arg, ((BoolExpr *) qual)->args)
                {
                        Expr       *subexpr = flatten_andors((Expr *) lfirst(arg));
 
@@ -327,7 +327,7 @@ flatten_andors(Expr *qual)
                         * with any other expr. Otherwise we'd need a listCopy here.
                         */
                        if (or_clause((Node *) subexpr))
-                               out_list = nconc(out_list, subexpr->args);
+                               out_list = nconc(out_list, ((BoolExpr *) subexpr)->args);
                        else
                                out_list = lappend(out_list, subexpr);
                }
@@ -335,20 +335,17 @@ flatten_andors(Expr *qual)
        }
        else if (not_clause((Node *) qual))
                return make_notclause(flatten_andors(get_notclausearg(qual)));
-       else if (is_opclause((Node *) qual))
+       else if (is_opclause(qual))
        {
+               OpExpr     *opexpr = (OpExpr *) qual;
                Expr       *left = (Expr *) get_leftop(qual);
                Expr       *right = (Expr *) get_rightop(qual);
 
-               if (right)
-                       return make_clause(qual->opType, qual->oper,
-                                                          lcons(flatten_andors(left),
-                                                                        lcons(flatten_andors(right),
-                                                                                  NIL)));
-               else
-                       return make_clause(qual->opType, qual->oper,
-                                                          lcons(flatten_andors(left),
-                                                                        NIL));
+               return make_opclause(opexpr->opno,
+                                                        opexpr->opresulttype,
+                                                        opexpr->opretset,
+                                                        flatten_andors(left),
+                                                        flatten_andors(right));
        }
        else
                return qual;
@@ -379,7 +376,8 @@ pull_ors(List *orlist)
                 * we'd need a listCopy here.
                 */
                if (or_clause((Node *) subexpr))
-                       out_list = nconc(out_list, pull_ors(subexpr->args));
+                       out_list = nconc(out_list,
+                                                        pull_ors(((BoolExpr *) subexpr)->args));
                else
                        out_list = lappend(out_list, subexpr);
        }
@@ -410,7 +408,8 @@ pull_ands(List *andlist)
                 * we'd need a listCopy here.
                 */
                if (and_clause((Node *) subexpr))
-                       out_list = nconc(out_list, pull_ands(subexpr->args));
+                       out_list = nconc(out_list,
+                                                        pull_ands(((BoolExpr *) subexpr)->args));
                else
                        out_list = lappend(out_list, subexpr);
        }
@@ -433,20 +432,17 @@ find_nots(Expr *qual)
 
 #ifdef NOT_USED
        /* recursing into operator expressions is probably not worth it. */
-       if (is_opclause((Node *) qual))
+       if (is_opclause(qual))
        {
+               OpExpr     *opexpr = (OpExpr *) qual;
                Expr       *left = (Expr *) get_leftop(qual);
                Expr       *right = (Expr *) get_rightop(qual);
 
-               if (right)
-                       return make_clause(qual->opType, qual->oper,
-                                                          lcons(find_nots(left),
-                                                                        lcons(find_nots(right),
-                                                                                  NIL)));
-               else
-                       return make_clause(qual->opType, qual->oper,
-                                                          lcons(find_nots(left),
-                                                                        NIL));
+               return make_opclause(opexpr->opno,
+                                                        opexpr->opresulttype,
+                                                        opexpr->opretset,
+                                                        find_nots(left),
+                                                        find_nots(right));
        }
 #endif
        if (and_clause((Node *) qual))
@@ -454,7 +450,7 @@ find_nots(Expr *qual)
                List       *t_list = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        t_list = lappend(t_list, find_nots(lfirst(temp)));
                return make_andclause(pull_ands(t_list));
        }
@@ -463,7 +459,7 @@ find_nots(Expr *qual)
                List       *t_list = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        t_list = lappend(t_list, find_nots(lfirst(temp)));
                return make_orclause(pull_ors(t_list));
        }
@@ -492,20 +488,17 @@ push_nots(Expr *qual)
         * Otherwise, retain the clause as it is (the 'not' can't be pushed
         * down any farther).
         */
-       if (is_opclause((Node *) qual))
+       if (is_opclause(qual))
        {
-               Oper       *oper = (Oper *) ((Expr *) qual)->oper;
-               Oid                     negator = get_negator(oper->opno);
+               OpExpr     *opexpr = (OpExpr *) qual;
+               Oid                     negator = get_negator(opexpr->opno);
 
                if (negator)
-               {
-                       Oper       *op = (Oper *) makeOper(negator,
-                                                                                          InvalidOid,
-                                                                                          oper->opresulttype,
-                                                                                          oper->opretset);
-
-                       return make_opclause(op, get_leftop(qual), get_rightop(qual));
-               }
+                       return make_opclause(negator,
+                                                                opexpr->opresulttype,
+                                                                opexpr->opretset,
+                                                                (Expr *) get_leftop(qual),
+                                                                (Expr *) get_rightop(qual));
                else
                        return make_notclause(qual);
        }
@@ -521,7 +514,7 @@ push_nots(Expr *qual)
                List       *t_list = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        t_list = lappend(t_list, push_nots(lfirst(temp)));
                return make_orclause(pull_ors(t_list));
        }
@@ -530,7 +523,7 @@ push_nots(Expr *qual)
                List       *t_list = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        t_list = lappend(t_list, push_nots(lfirst(temp)));
                return make_andclause(pull_ands(t_list));
        }
@@ -576,7 +569,7 @@ find_ors(Expr *qual)
                List       *andlist = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        andlist = lappend(andlist, find_ors(lfirst(temp)));
                return make_andclause(pull_ands(andlist));
        }
@@ -585,7 +578,7 @@ find_ors(Expr *qual)
                List       *orlist = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        orlist = lappend(orlist, find_ors(lfirst(temp)));
                return or_normalize(pull_ors(orlist));
        }
@@ -629,7 +622,7 @@ or_normalize(List *orlist)
 
                if (and_clause((Node *) clause))
                {
-                       int                     nclauses = length(clause->args);
+                       int                     nclauses = length(((BoolExpr *) clause)->args);
 
                        if (nclauses > num_subclauses)
                        {
@@ -650,7 +643,7 @@ or_normalize(List *orlist)
         */
        orlist = lremove(distributable, orlist);
 
-       foreach(temp, distributable->args)
+       foreach(temp, ((BoolExpr *) distributable)->args)
        {
                Expr       *andclause = lfirst(temp);
                List       *neworlist;
@@ -703,7 +696,7 @@ find_ands(Expr *qual)
                List       *orlist = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        orlist = lappend(orlist, find_ands(lfirst(temp)));
                return make_orclause(pull_ors(orlist));
        }
@@ -712,7 +705,7 @@ find_ands(Expr *qual)
                List       *andlist = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        andlist = lappend(andlist, find_ands(lfirst(temp)));
                return and_normalize(pull_ands(andlist));
        }
@@ -757,7 +750,7 @@ and_normalize(List *andlist)
 
                if (or_clause((Node *) clause))
                {
-                       int                     nclauses = length(clause->args);
+                       int                     nclauses = length(((BoolExpr *) clause)->args);
 
                        if (nclauses > num_subclauses)
                        {
@@ -778,7 +771,7 @@ and_normalize(List *andlist)
         */
        andlist = lremove(distributable, andlist);
 
-       foreach(temp, distributable->args)
+       foreach(temp, ((BoolExpr *) distributable)->args)
        {
                Expr       *orclause = lfirst(temp);
                List       *newandlist;
@@ -829,7 +822,7 @@ qual_cleanup(Expr *qual)
                List       *andlist = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        andlist = lappend(andlist, qual_cleanup(lfirst(temp)));
 
                andlist = remove_duplicates(pull_ands(andlist));
@@ -844,7 +837,7 @@ qual_cleanup(Expr *qual)
                List       *orlist = NIL;
                List       *temp;
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                        orlist = lappend(orlist, qual_cleanup(lfirst(temp)));
 
                orlist = remove_duplicates(pull_ors(orlist));
@@ -910,7 +903,7 @@ count_bool_nodes(Expr *qual,
                *nodes = *cnfnodes = 0.0;
                *dnfnodes = 1.0;                /* DNF nodes will be product of sub-counts */
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                {
                        count_bool_nodes(lfirst(temp),
                                                         &subnodes, &subcnfnodes, &subdnfnodes);
@@ -931,7 +924,7 @@ count_bool_nodes(Expr *qual,
                *nodes = *dnfnodes = 0.0;
                *cnfnodes = 1.0;                /* CNF nodes will be product of sub-counts */
 
-               foreach(temp, qual->args)
+               foreach(temp, ((BoolExpr *) qual)->args)
                {
                        count_bool_nodes(lfirst(temp),
                                                         &subnodes, &subcnfnodes, &subdnfnodes);
index 6889514..87d3c98 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.58 2002/11/25 21:29:40 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.59 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -96,7 +96,7 @@ preprocess_targetlist(List *tlist,
                if (command_type == CMD_DELETE)
                        tlist = listCopy(tlist);
 
-               tlist = lappend(tlist, makeTargetEntry(resdom, (Node *) var));
+               tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) var));
        }
 
        return tlist;
@@ -215,7 +215,7 @@ expand_targetlist(List *tlist, int command_type,
                                                                                                 atttypmod,
                                                                          pstrdup(NameStr(att_tup->attname)),
                                                                                                 false),
-                                                                         new_expr);
+                                                                         (Expr *) new_expr);
                }
 
                new_tlist = lappend(new_tlist, new_tle);
index 79063c0..a55af2e 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.81 2002/11/25 21:29:40 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.82 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -406,7 +406,7 @@ generate_setop_tlist(List *colTypes, int flag,
                 * the output tlists of upper-level nodes!
                 */
                if (hack_constants && inputtle->expr && IsA(inputtle->expr, Const))
-                       expr = inputtle->expr;
+                       expr = (Node *) inputtle->expr;
                else
                        expr = (Node *) makeVar(0,
                                                                        inputtle->resdom->resno,
@@ -430,7 +430,7 @@ generate_setop_tlist(List *colTypes, int flag,
                                                        colTypmod,
                                                        pstrdup(reftle->resdom->resname),
                                                        false);
-               tlist = lappend(tlist, makeTargetEntry(resdom, expr));
+               tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
                input_tlist = lnext(input_tlist);
                refnames_tlist = lnext(refnames_tlist);
        }
@@ -449,7 +449,7 @@ generate_setop_tlist(List *colTypes, int flag,
                                                                  Int32GetDatum(flag),
                                                                  false,
                                                                  true);
-               tlist = lappend(tlist, makeTargetEntry(resdom, expr));
+               tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
        }
 
        return tlist;
@@ -543,7 +543,7 @@ generate_append_tlist(List *colTypes, bool flag,
                                                        colTypmod,
                                                        pstrdup(reftle->resdom->resname),
                                                        false);
-               tlist = lappend(tlist, makeTargetEntry(resdom, expr));
+               tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
                refnames_tlist = lnext(refnames_tlist);
        }
 
@@ -561,7 +561,7 @@ generate_append_tlist(List *colTypes, bool flag,
                                                                INT4OID,
                                                                -1,
                                                                0);
-               tlist = lappend(tlist, makeTargetEntry(resdom, expr));
+               tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
        }
 
        pfree(colTypmods);
@@ -872,13 +872,13 @@ adjust_inherited_attrs_mutator(Node *node,
         */
        if (is_subplan(node))
        {
-               SubPlan    *subplan;
+               SubPlanExpr *subplan;
 
                /* Copy the node and process subplan args */
                node = expression_tree_mutator(node, adjust_inherited_attrs_mutator,
                                                                           (void *) context);
                /* Make sure we have separate copies of subplan and its rtable */
-               subplan = (SubPlan *) ((Expr *) node)->oper;
+               subplan = (SubPlanExpr *) node;
                subplan->plan = copyObject(subplan->plan);
                subplan->rtable = copyObject(subplan->rtable);
                return node;
index a0d1b75..ef317c5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.115 2002/12/01 21:05:14 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.116 2002/12/12 15:49:32 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -70,84 +70,41 @@ static bool contain_mutable_functions_walker(Node *node, void *context);
 static bool contain_volatile_functions_walker(Node *node, void *context);
 static bool contain_nonstrict_functions_walker(Node *node, void *context);
 static Node *eval_const_expressions_mutator(Node *node, List *active_fns);
-static Expr *simplify_op_or_func(Expr *expr, List *args, bool allow_inline,
-                                                                List *active_fns);
-static Expr *evaluate_op_or_func(Expr *expr, List *args, HeapTuple func_tuple);
-static Expr *inline_op_or_func(Expr *expr, List *args, HeapTuple func_tuple,
+static Expr *simplify_function(Oid funcid, List *args, bool allow_inline,
                                                           List *active_fns);
+static Expr *evaluate_function(Oid funcid, List *args, HeapTuple func_tuple);
+static Expr *inline_function(Oid funcid, List *args, HeapTuple func_tuple,
+                                                        List *active_fns);
 static Node *substitute_actual_parameters(Node *expr, int nargs, List *args,
                                                                                  int *usecounts);
 static Node *substitute_actual_parameters_mutator(Node *node,
                                         substitute_actual_parameters_context *context);
 
 
-Expr *
-make_clause(int type, Node *oper, List *args)
-{
-       Expr       *expr = makeNode(Expr);
-
-       switch (type)
-       {
-               case AND_EXPR:
-               case OR_EXPR:
-               case NOT_EXPR:
-                       expr->typeOid = BOOLOID;
-                       break;
-               case OP_EXPR:
-               case DISTINCT_EXPR:
-                       expr->typeOid = ((Oper *) oper)->opresulttype;
-                       break;
-               case FUNC_EXPR:
-                       expr->typeOid = ((Func *) oper)->funcresulttype;
-                       break;
-               default:
-                       elog(ERROR, "make_clause: unsupported type %d", type);
-                       break;
-       }
-       expr->opType = type;
-       expr->oper = oper;                      /* ignored for AND, OR, NOT */
-       expr->args = args;
-       return expr;
-}
-
-
 /*****************************************************************************
  *             OPERATOR clause functions
  *****************************************************************************/
 
-
-/*
- * is_opclause
- *
- * Returns t iff the clause is an operator clause:
- *                             (op expr expr) or (op expr).
- */
-bool
-is_opclause(Node *clause)
-{
-       return (clause != NULL &&
-                       IsA(clause, Expr) &&
-                       ((Expr *) clause)->opType == OP_EXPR);
-}
-
 /*
  * make_opclause
- *       Creates a clause given its operator, left operand, and right
- *       operand (pass NULL to create single-operand clause).
+ *       Creates an operator clause given its operator info, left operand,
+ *       and right operand (pass NULL to create single-operand clause).
  */
 Expr *
-make_opclause(Oper *op, Var *leftop, Var *rightop)
+make_opclause(Oid opno, Oid opresulttype, bool opretset,
+                         Expr *leftop, Expr *rightop)
 {
-       Expr       *expr = makeNode(Expr);
+       OpExpr     *expr = makeNode(OpExpr);
 
-       expr->typeOid = op->opresulttype;
-       expr->opType = OP_EXPR;
-       expr->oper = (Node *) op;
+       expr->opno = opno;
+       expr->opfuncid = InvalidOid;
+       expr->opresulttype = opresulttype;
+       expr->opretset = opretset;
        if (rightop)
                expr->args = makeList2(leftop, rightop);
        else
                expr->args = makeList1(leftop);
-       return expr;
+       return (Expr *) expr;
 }
 
 /*
@@ -163,8 +120,10 @@ make_opclause(Oper *op, Var *leftop, Var *rightop)
 Var *
 get_leftop(Expr *clause)
 {
-       if (clause->args != NULL)
-               return lfirst(clause->args);
+       OpExpr *expr = (OpExpr *) clause;
+
+       if (expr->args != NULL)
+               return lfirst(expr->args);
        else
                return NULL;
 }
@@ -178,124 +137,109 @@ get_leftop(Expr *clause)
 Var *
 get_rightop(Expr *clause)
 {
-       if (clause->args != NULL && lnext(clause->args) != NULL)
-               return lfirst(lnext(clause->args));
+       OpExpr *expr = (OpExpr *) clause;
+
+       if (expr->args != NULL && lnext(expr->args) != NULL)
+               return lfirst(lnext(expr->args));
        else
                return NULL;
 }
 
 /*****************************************************************************
- *             FUNC clause functions
+ *             FUNCTION clause functions
  *****************************************************************************/
 
 /*
- * is_funcclause
- *
- * Returns t iff the clause is a function clause: (func { expr }).
- */
-bool
-is_funcclause(Node *clause)
-{
-       return (clause != NULL &&
-                       IsA(clause, Expr) &&
-                       ((Expr *) clause)->opType == FUNC_EXPR);
-}
-
-/*
  * make_funcclause
- *
- * Creates a function clause given the FUNC node and the functional
- * arguments.
+ *       Creates a function clause given its function info and argument list.
  */
 Expr *
-make_funcclause(Func *func, List *funcargs)
+make_funcclause(Oid funcid, Oid funcresulttype, bool funcretset,
+                               CoercionForm funcformat, List *funcargs)
 {
-       Expr       *expr = makeNode(Expr);
+       FuncExpr   *expr = makeNode(FuncExpr);
 
-       expr->typeOid = func->funcresulttype;
-       expr->opType = FUNC_EXPR;
-       expr->oper = (Node *) func;
+       expr->funcid = funcid;
+       expr->funcresulttype = funcresulttype;
+       expr->funcretset = funcretset;
+       expr->funcformat = funcformat;
        expr->args = funcargs;
-       return expr;
+       return (Expr *) expr;
 }
 
 /*****************************************************************************
- *             OR clause functions
+ *             NOT clause functions
  *****************************************************************************/
 
 /*
- * or_clause
+ * not_clause
  *
- * Returns t iff the clause is an 'or' clause: (OR { expr }).
+ * Returns t iff this is a 'not' clause: (NOT expr).
  */
 bool
-or_clause(Node *clause)
+not_clause(Node *clause)
 {
        return (clause != NULL &&
-                       IsA(clause, Expr) &&
-                       ((Expr *) clause)->opType == OR_EXPR);
+                       IsA(clause, BoolExpr) &&
+                       ((BoolExpr *) clause)->boolop == NOT_EXPR);
 }
 
 /*
- * make_orclause
+ * make_notclause
  *
- * Creates an 'or' clause given a list of its subclauses.
+ * Create a 'not' clause given the expression to be negated.
  */
 Expr *
-make_orclause(List *orclauses)
+make_notclause(Expr *notclause)
 {
-       Expr       *expr = makeNode(Expr);
+       BoolExpr   *expr = makeNode(BoolExpr);
 
-       expr->typeOid = BOOLOID;
-       expr->opType = OR_EXPR;
-       expr->oper = NULL;
-       expr->args = orclauses;
-       return expr;
+       expr->boolop = NOT_EXPR;
+       expr->args = makeList1(notclause);
+       return (Expr *) expr;
 }
 
-/*****************************************************************************
- *             NOT clause functions
- *****************************************************************************/
-
 /*
- * not_clause
+ * get_notclausearg
  *
- * Returns t iff this is a 'not' clause: (NOT expr).
+ * Retrieve the clause within a 'not' clause
  */
-bool
-not_clause(Node *clause)
+Expr *
+get_notclausearg(Expr *notclause)
 {
-       return (clause != NULL &&
-                       IsA(clause, Expr) &&
-                       ((Expr *) clause)->opType == NOT_EXPR);
+       return lfirst(((BoolExpr *) notclause)->args);
 }
 
+/*****************************************************************************
+ *             OR clause functions
+ *****************************************************************************/
+
 /*
- * make_notclause
+ * or_clause
  *
- * Create a 'not' clause given the expression to be negated.
+ * Returns t iff the clause is an 'or' clause: (OR { expr }).
  */
-Expr *
-make_notclause(Expr *notclause)
+bool
+or_clause(Node *clause)
 {
-       Expr       *expr = makeNode(Expr);
-
-       expr->typeOid = BOOLOID;
-       expr->opType = NOT_EXPR;
-       expr->oper = NULL;
-       expr->args = makeList1(notclause);
-       return expr;
+       return (clause != NULL &&
+                       IsA(clause, BoolExpr) &&
+                       ((BoolExpr *) clause)->boolop == OR_EXPR);
 }
 
 /*
- * get_notclausearg
+ * make_orclause
  *
- * Retrieve the clause within a 'not' clause
+ * Creates an 'or' clause given a list of its subclauses.
  */
 Expr *
-get_notclausearg(Expr *notclause)
+make_orclause(List *orclauses)
 {
-       return lfirst(notclause->args);
+       BoolExpr   *expr = makeNode(BoolExpr);
+
+       expr->boolop = OR_EXPR;
+       expr->args = orclauses;
+       return (Expr *) expr;
 }
 
 /*****************************************************************************
@@ -312,25 +256,23 @@ bool
 and_clause(Node *clause)
 {
        return (clause != NULL &&
-                       IsA(clause, Expr) &&
-                       ((Expr *) clause)->opType == AND_EXPR);
+                       IsA(clause, BoolExpr) &&
+                       ((BoolExpr *) clause)->boolop == AND_EXPR);
 }
 
 /*
  * make_andclause
  *
- * Create an 'and' clause given its arguments in a list.
+ * Creates an 'and' clause given a list of its subclauses.
  */
 Expr *
 make_andclause(List *andclauses)
 {
-       Expr       *expr = makeNode(Expr);
+       BoolExpr   *expr = makeNode(BoolExpr);
 
-       expr->typeOid = BOOLOID;
-       expr->opType = AND_EXPR;
-       expr->oper = NULL;
+       expr->boolop = AND_EXPR;
        expr->args = andclauses;
-       return expr;
+       return (Expr *) expr;
 }
 
 /*
@@ -382,7 +324,7 @@ make_ands_implicit(Expr *clause)
        if (clause == NULL)
                return NIL;                             /* NULL -> NIL list == TRUE */
        else if (and_clause((Node *) clause))
-               return clause->args;
+               return ((BoolExpr *) clause)->args;
        else if (IsA(clause, Const) &&
                         !((Const *) clause)->constisnull &&
                         DatumGetBool(((Const *) clause)->constvalue))
@@ -476,7 +418,7 @@ pull_agg_clause_walker(Node *node, List **listptr)
                 * Complain if the aggregate's argument contains any aggregates;
                 * nested agg functions are semantically nonsensical.
                 */
-               if (contain_agg_clause(((Aggref *) node)->target))
+               if (contain_agg_clause((Node *) ((Aggref *) node)->target))
                        elog(ERROR, "Aggregate function calls may not be nested");
 
                /*
@@ -512,38 +454,41 @@ expression_returns_set_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr))
        {
-               Expr       *expr = (Expr *) node;
+               FuncExpr   *expr = (FuncExpr *) node;
 
-               switch (expr->opType)
-               {
-                       case OP_EXPR:
-                       case DISTINCT_EXPR:
-                               if (((Oper *) expr->oper)->opretset)
-                                       return true;
-                               /* else fall through to check args */
-                               break;
-                       case FUNC_EXPR:
-                               if (((Func *) expr->oper)->funcretset)
-                                       return true;
-                               /* else fall through to check args */
-                               break;
-                       case OR_EXPR:
-                       case AND_EXPR:
-                       case NOT_EXPR:
-                               /* Booleans can't return a set, so no need to recurse */
-                               return false;
-                       case SUBPLAN_EXPR:
-                               /* Subplans can't presently return sets either */
-                               return false;
-               }
+               if (expr->funcretset)
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, OpExpr))
+       {
+               OpExpr   *expr = (OpExpr *) node;
+
+               if (expr->opretset)
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, DistinctExpr))
+       {
+               DistinctExpr   *expr = (DistinctExpr *) node;
+
+               if (expr->opretset)
+                       return true;
+               /* else fall through to check args */
        }
-       /* Avoid recursion for some other cases that can't return a set */
+
+       /* Avoid recursion for some cases that can't return a set */
+       if (IsA(node, BoolExpr))
+               return false;
        if (IsA(node, Aggref))
                return false;
        if (IsA(node, SubLink))
                return false;
+       if (IsA(node, SubPlanExpr))
+               return false;
+
        return expression_tree_walker(node, expression_returns_set_walker,
                                                                  context);
 }
@@ -574,7 +519,8 @@ contain_subplans_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (is_subplan(node) || IsA(node, SubLink))
+       if (IsA(node, SubPlanExpr) ||
+               IsA(node, SubLink))
                return true;                    /* abort the tree traversal and return
                                                                 * true */
        return expression_tree_walker(node, contain_subplans_walker, context);
@@ -584,8 +530,8 @@ contain_subplans_walker(Node *node, void *context)
  * pull_subplans
  *       Recursively pulls all subplans from an expression tree.
  *
- *       Returns list of subplan nodes found.  Note the nodes themselves are not
- *       copied, only referenced.
+ *       Returns list of SubPlanExpr nodes found.  Note the nodes themselves
+ *       are not copied, only referenced.
  */
 List *
 pull_subplans(Node *clause)
@@ -603,7 +549,7 @@ pull_subplans_walker(Node *node, List **listptr)
                return false;
        if (is_subplan(node))
        {
-               *listptr = lappend(*listptr, ((Expr *) node)->oper);
+               *listptr = lappend(*listptr, node);
                /* fall through to check args to subplan */
        }
        return expression_tree_walker(node, pull_subplans_walker,
@@ -710,7 +656,7 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
                 */
                List       *t;
 
-               foreach(t, ((Expr *) node)->args)
+               foreach(t, ((SubPlanExpr *) node)->args)
                {
                        Node       *thisarg = lfirst(t);
                        Var                *var;
@@ -789,24 +735,29 @@ contain_mutable_functions_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr))
        {
-               Expr       *expr = (Expr *) node;
+               FuncExpr   *expr = (FuncExpr *) node;
 
-               switch (expr->opType)
-               {
-                       case OP_EXPR:
-                       case DISTINCT_EXPR:
-                               if (op_volatile(((Oper *) expr->oper)->opno) != PROVOLATILE_IMMUTABLE)
-                                       return true;
-                               break;
-                       case FUNC_EXPR:
-                               if (func_volatile(((Func *) expr->oper)->funcid) != PROVOLATILE_IMMUTABLE)
-                                       return true;
-                               break;
-                       default:
-                               break;
-               }
+               if (func_volatile(expr->funcid) != PROVOLATILE_IMMUTABLE)
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, OpExpr))
+       {
+               OpExpr   *expr = (OpExpr *) node;
+
+               if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE)
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, DistinctExpr))
+       {
+               DistinctExpr   *expr = (DistinctExpr *) node;
+
+               if (op_volatile(expr->opno) != PROVOLATILE_IMMUTABLE)
+                       return true;
+               /* else fall through to check args */
        }
        return expression_tree_walker(node, contain_mutable_functions_walker,
                                                                  context);
@@ -839,24 +790,29 @@ contain_volatile_functions_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr))
        {
-               Expr       *expr = (Expr *) node;
+               FuncExpr   *expr = (FuncExpr *) node;
 
-               switch (expr->opType)
-               {
-                       case OP_EXPR:
-                       case DISTINCT_EXPR:
-                               if (op_volatile(((Oper *) expr->oper)->opno) == PROVOLATILE_VOLATILE)
-                                       return true;
-                               break;
-                       case FUNC_EXPR:
-                               if (func_volatile(((Func *) expr->oper)->funcid) == PROVOLATILE_VOLATILE)
-                                       return true;
-                               break;
-                       default:
-                               break;
-               }
+               if (func_volatile(expr->funcid) == PROVOLATILE_VOLATILE)
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, OpExpr))
+       {
+               OpExpr   *expr = (OpExpr *) node;
+
+               if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE)
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, DistinctExpr))
+       {
+               DistinctExpr   *expr = (DistinctExpr *) node;
+
+               if (op_volatile(expr->opno) == PROVOLATILE_VOLATILE)
+                       return true;
+               /* else fall through to check args */
        }
        return expression_tree_walker(node, contain_volatile_functions_walker,
                                                                  context);
@@ -876,7 +832,7 @@ contain_volatile_functions_walker(Node *node, void *context)
  *
  * XXX we do not examine sublinks/subplans to see if they contain uses of
  * nonstrict functions.        It's not real clear if that is correct or not...
- * for the current usage it does not matter, since inline_op_or_func()
+ * for the current usage it does not matter, since inline_function()
  * rejects cases with sublinks.
  */
 bool
@@ -890,23 +846,33 @@ contain_nonstrict_functions_walker(Node *node, void *context)
 {
        if (node == NULL)
                return false;
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr))
+       {
+               FuncExpr   *expr = (FuncExpr *) node;
+
+               if (!func_strict(expr->funcid))
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, OpExpr))
+       {
+               OpExpr   *expr = (OpExpr *) node;
+
+               if (!op_strict(expr->opno))
+                       return true;
+               /* else fall through to check args */
+       }
+       if (IsA(node, DistinctExpr))
+       {
+               /* IS DISTINCT FROM is inherently non-strict */
+               return true;
+       }
+       if (IsA(node, BoolExpr))
        {
-               Expr       *expr = (Expr *) node;
+               BoolExpr   *expr = (BoolExpr *) node;
 
-               switch (expr->opType)
+               switch (expr->boolop)
                {
-                       case OP_EXPR:
-                               if (!op_strict(((Oper *) expr->oper)->opno))
-                                       return true;
-                               break;
-                       case DISTINCT_EXPR:
-                               /* IS DISTINCT FROM is inherently non-strict */
-                               return true;
-                       case FUNC_EXPR:
-                               if (!func_strict(((Func *) expr->oper)->funcid))
-                                       return true;
-                               break;
                        case OR_EXPR:
                        case AND_EXPR:
                                /* OR, AND are inherently non-strict */
@@ -1147,39 +1113,28 @@ NumRelids(Node *clause)
  * XXX the clause is destructively modified!
  */
 void
-CommuteClause(Expr *clause)
+CommuteClause(OpExpr *clause)
 {
        Oid                     opoid;
-       HeapTuple       optup;
-       Form_pg_operator commuTup;
-       Oper       *commu;
        Node       *temp;
 
-       if (!is_opclause((Node *) clause) ||
+       if (!is_opclause(clause) ||
                length(clause->args) != 2)
                elog(ERROR, "CommuteClause: applied to non-binary-operator clause");
 
-       opoid = ((Oper *) clause->oper)->opno;
-
-       optup = SearchSysCache(OPEROID,
-                                                  ObjectIdGetDatum(get_commutator(opoid)),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(optup))
-               elog(ERROR, "CommuteClause: no commutator for operator %u", opoid);
-
-       commuTup = (Form_pg_operator) GETSTRUCT(optup);
+       opoid = get_commutator(clause->opno);
 
-       commu = makeOper(HeapTupleGetOid(optup),
-                                        commuTup->oprcode,
-                                        commuTup->oprresult,
-                                        ((Oper *) clause->oper)->opretset);
-
-       ReleaseSysCache(optup);
+       if (!OidIsValid(opoid))
+               elog(ERROR, "CommuteClause: no commutator for operator %u",
+                        clause->opno);
 
        /*
-        * re-form the clause in-place!
+        * modify the clause in-place!
         */
-       clause->oper = (Node *) commu;
+       clause->opno = opoid;
+       clause->opfuncid = InvalidOid;
+       /* opresulttype and opretset are assumed not to change */
+
        temp = lfirst(clause->args);
        lfirst(clause->args) = lsecond(clause->args);
        lsecond(clause->args) = temp;
@@ -1223,15 +1178,94 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 {
        if (node == NULL)
                return NULL;
-       if (IsA(node, Expr))
+       if (IsA(node, FuncExpr))
        {
-               Expr       *expr = (Expr *) node;
+               FuncExpr   *expr = (FuncExpr *) node;
                List       *args;
-               Const      *const_input;
-               Expr       *newexpr;
+               Expr       *simple;
+               FuncExpr   *newexpr;
+
+               /*
+                * Reduce constants in the FuncExpr's arguments.  We know args is
+                * either NIL or a List node, so we can call
+                * expression_tree_mutator directly rather than recursing to self.
+                */
+               args = (List *) expression_tree_mutator((Node *) expr->args,
+                                                                                 eval_const_expressions_mutator,
+                                                                                               (void *) active_fns);
+               /*
+                * Code for op/func reduction is pretty bulky, so split it out
+                * as a separate function.
+                */
+               simple = simplify_function(expr->funcid, args, true, active_fns);
+               if (simple)                             /* successfully simplified it */
+                       return (Node *) simple;
+               /*
+                * The expression cannot be simplified any further, so build and
+                * return a replacement FuncExpr node using the possibly-simplified
+                * arguments.
+                */
+               newexpr = makeNode(FuncExpr);
+               newexpr->funcid = expr->funcid;
+               newexpr->funcresulttype = expr->funcresulttype;
+               newexpr->funcretset = expr->funcretset;
+               newexpr->funcformat = expr->funcformat;
+               newexpr->args = args;
+               return (Node *) newexpr;
+       }
+       if (IsA(node, OpExpr))
+       {
+               OpExpr     *expr = (OpExpr *) node;
+               List       *args;
+               Expr       *simple;
+               OpExpr     *newexpr;
 
                /*
-                * Reduce constants in the Expr's arguments.  We know args is
+                * Reduce constants in the OpExpr's arguments.  We know args is
+                * either NIL or a List node, so we can call
+                * expression_tree_mutator directly rather than recursing to self.
+                */
+               args = (List *) expression_tree_mutator((Node *) expr->args,
+                                                                                 eval_const_expressions_mutator,
+                                                                                               (void *) active_fns);
+               /*
+                * Need to get OID of underlying function.  Okay to scribble on
+                * input to this extent.
+                */
+               set_opfuncid(expr);
+               /*
+                * Code for op/func reduction is pretty bulky, so split it out
+                * as a separate function.
+                */
+               simple = simplify_function(expr->opfuncid, args, true, active_fns);
+               if (simple)                             /* successfully simplified it */
+                       return (Node *) simple;
+               /*
+                * The expression cannot be simplified any further, so build and
+                * return a replacement OpExpr node using the possibly-simplified
+                * arguments.
+                */
+               newexpr = makeNode(OpExpr);
+               newexpr->opno = expr->opno;
+               newexpr->opfuncid = expr->opfuncid;
+               newexpr->opresulttype = expr->opresulttype;
+               newexpr->opretset = expr->opretset;
+               newexpr->args = args;
+               return (Node *) newexpr;
+       }
+       if (IsA(node, DistinctExpr))
+       {
+               DistinctExpr *expr = (DistinctExpr *) node;
+               List       *args;
+               List       *arg;
+               bool            has_null_input = false;
+               bool            all_null_input = true;
+               bool            has_nonconst_input = false;
+               Expr       *simple;
+               DistinctExpr *newexpr;
+
+               /*
+                * Reduce constants in the DistinctExpr's arguments.  We know args is
                 * either NIL or a List node, so we can call
                 * expression_tree_mutator directly rather than recursing to self.
                 */
@@ -1239,76 +1273,83 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                                                                                  eval_const_expressions_mutator,
                                                                                                (void *) active_fns);
 
-               switch (expr->opType)
+               /*
+                * We must do our own check for NULLs because
+                * DistinctExpr has different results for NULL input
+                * than the underlying operator does.
+                */
+               foreach(arg, args)
                {
-                       case OP_EXPR:
-                       case FUNC_EXPR:
+                       if (IsA(lfirst(arg), Const))
+                       {
+                               has_null_input |= ((Const *) lfirst(arg))->constisnull;
+                               all_null_input &= ((Const *) lfirst(arg))->constisnull;
+                       }
+                       else
+                               has_nonconst_input = true;
+               }
 
-                               /*
-                                * Code for op/func case is pretty bulky, so split it out
-                                * as a separate function.
-                                */
-                               newexpr = simplify_op_or_func(expr, args,
-                                                                                         true, active_fns);
-                               if (newexpr)    /* successfully simplified it */
-                                       return (Node *) newexpr;
+               /* all constants? then can optimize this out */
+               if (!has_nonconst_input)
+               {
+                       /* all nulls? then not distinct */
+                       if (all_null_input)
+                               return MAKEBOOLCONST(false, false);
 
-                               /*
-                                * else fall out to build new Expr node with simplified
-                                * args
-                                */
-                               break;
-                       case DISTINCT_EXPR:
-                               {
-                                       List       *arg;
-                                       bool            has_null_input = false;
-                                       bool            all_null_input = true;
-                                       bool            has_nonconst_input = false;
+                       /* one null? then distinct */
+                       if (has_null_input)
+                               return MAKEBOOLCONST(true, false);
 
-                                       /*
-                                        * We must do our own check for NULLs because
-                                        * DISTINCT_EXPR has different results for NULL input
-                                        * than the underlying operator does.
-                                        */
-                                       foreach(arg, args)
-                                       {
-                                               if (IsA(lfirst(arg), Const))
-                                               {
-                                                       has_null_input |= ((Const *) lfirst(arg))->constisnull;
-                                                       all_null_input &= ((Const *) lfirst(arg))->constisnull;
-                                               }
-                                               else
-                                                       has_nonconst_input = true;
-                                       }
+                       /* otherwise try to evaluate the '=' operator */
+                       /* (NOT okay to try to inline it, though!) */
 
-                                       /* all constants? then can optimize this out */
-                                       if (!has_nonconst_input)
-                                       {
-                                               /* all nulls? then not distinct */
-                                               if (all_null_input)
-                                                       return MAKEBOOLCONST(false, false);
-
-                                               /* one null? then distinct */
-                                               if (has_null_input)
-                                                       return MAKEBOOLCONST(true, false);
-
-                                               /* otherwise try to evaluate the '=' operator */
-                                               /* (NOT okay to try to inline it, though!) */
-                                               newexpr = simplify_op_or_func(expr, args,
-                                                                                                         false, active_fns);
-                                               if (newexpr)    /* successfully simplified it */
-                                                       return (Node *) newexpr;
-                                       }
+                       /*
+                        * Need to get OID of underlying function.  Okay to scribble on
+                        * input to this extent.
+                        */
+                       set_opfuncid((OpExpr *) expr); /* rely on struct equivalence */
+                       /*
+                        * Code for op/func reduction is pretty bulky, so split it out
+                        * as a separate function.
+                        */
+                       simple = simplify_function(expr->opfuncid, args,
+                                                                          false, active_fns);
+                       if (simple)                     /* successfully simplified it */
+                               return (Node *) simple;
+               }
 
-                                       /*
-                                        * else fall out to build new Expr node with simplified
-                                        * args
-                                        */
-                                       break;
-                               }
+               /*
+                * The expression cannot be simplified any further, so build and
+                * return a replacement DistinctExpr node using the
+                * possibly-simplified arguments.
+                */
+               newexpr = makeNode(DistinctExpr);
+               newexpr->opno = expr->opno;
+               newexpr->opfuncid = expr->opfuncid;
+               newexpr->opresulttype = expr->opresulttype;
+               newexpr->opretset = expr->opretset;
+               newexpr->args = args;
+               return (Node *) newexpr;
+       }
+       if (IsA(node, BoolExpr))
+       {
+               BoolExpr   *expr = (BoolExpr *) node;
+               List       *args;
+               Const      *const_input;
+
+               /*
+                * Reduce constants in the BoolExpr's arguments.  We know args is
+                * either NIL or a List node, so we can call
+                * expression_tree_mutator directly rather than recursing to self.
+                */
+               args = (List *) expression_tree_mutator((Node *) expr->args,
+                                                                                 eval_const_expressions_mutator,
+                                                                                               (void *) active_fns);
+
+               switch (expr->boolop)
+               {
                        case OR_EXPR:
                                {
-
                                        /*----------
                                         * OR arguments are handled as follows:
                                         *      non constant: keep
@@ -1361,7 +1402,6 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                                }
                        case AND_EXPR:
                                {
-
                                        /*----------
                                         * AND arguments are handled as follows:
                                         *      non constant: keep
@@ -1414,47 +1454,34 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                                }
                        case NOT_EXPR:
                                Assert(length(args) == 1);
-                               if (!IsA(lfirst(args), Const))
-                                       break;
-                               const_input = (Const *) lfirst(args);
-                               /* NOT NULL => NULL */
-                               if (const_input->constisnull)
-                                       return MAKEBOOLCONST(false, true);
-                               /* otherwise pretty easy */
-                               return MAKEBOOLCONST(!DatumGetBool(const_input->constvalue),
-                                                                        false);
-                       case SUBPLAN_EXPR:
-
-                               /*
-                                * Return a SubPlan unchanged --- too late to do anything
-                                * with it.  The arglist simplification above was wasted
-                                * work (the list probably only contains Var nodes
-                                * anyway).
-                                *
-                                * XXX should we elog() here instead?  Probably this routine
-                                * should never be invoked after SubPlan creation.
-                                */
-                               return (Node *) expr;
+                               if (IsA(lfirst(args), Const))
+                               {
+                                       const_input = (Const *) lfirst(args);
+                                       /* NOT NULL => NULL */
+                                       if (const_input->constisnull)
+                                               return MAKEBOOLCONST(false, true);
+                                       /* otherwise pretty easy */
+                                       return MAKEBOOLCONST(!DatumGetBool(const_input->constvalue),
+                                                                                false);
+                               }
+                               /* Else we still need a NOT node */
+                               return (Node *) make_notclause(lfirst(args));
                        default:
-                               elog(ERROR, "eval_const_expressions: unexpected opType %d",
-                                        (int) expr->opType);
+                               elog(ERROR, "eval_const_expressions: unexpected boolop %d",
+                                        (int) expr->boolop);
                                break;
                }
-
+       }
+       if (IsA(node, SubPlanExpr))
+       {
                /*
-                * If we break out of the above switch on opType, then the
-                * expression cannot be simplified any further, so build and
-                * return a replacement Expr node using the possibly-simplified
-                * arguments and the original oper node. Can't use make_clause()
-                * here because we want to be sure the typeOid field is
-                * preserved...
+                * Return a SubPlanExpr unchanged --- too late to do anything
+                * with it.
+                *
+                * XXX should we elog() here instead?  Probably this routine
+                * should never be invoked after SubPlanExpr creation.
                 */
-               newexpr = makeNode(Expr);
-               newexpr->typeOid = expr->typeOid;
-               newexpr->opType = expr->opType;
-               newexpr->oper = expr->oper;
-               newexpr->args = args;
-               return (Node *) newexpr;
+               return node;
        }
        if (IsA(node, RelabelType))
        {
@@ -1466,14 +1493,15 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                RelabelType *relabel = (RelabelType *) node;
                Node       *arg;
 
-               arg = eval_const_expressions_mutator(relabel->arg, active_fns);
+               arg = eval_const_expressions_mutator((Node *) relabel->arg,
+                                                                                        active_fns);
 
                /*
                 * If we find stacked RelabelTypes (eg, from foo :: int :: oid) we
                 * can discard all but the top one.
                 */
                while (arg && IsA(arg, RelabelType))
-                       arg = ((RelabelType *) arg)->arg;
+                       arg = (Node *) ((RelabelType *) arg)->arg;
 
                if (arg && IsA(arg, Const))
                {
@@ -1493,7 +1521,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                {
                        RelabelType *newrelabel = makeNode(RelabelType);
 
-                       newrelabel->arg = arg;
+                       newrelabel->arg = (Expr *) arg;
                        newrelabel->resulttype = relabel->resulttype;
                        newrelabel->resulttypmod = relabel->resulttypmod;
                        return (Node *) newrelabel;
@@ -1545,7 +1573,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                         * alternative, the CASE reduces to just this alternative.
                         */
                        if (newargs == NIL)
-                               return casewhen->result;
+                               return (Node *) casewhen->result;
 
                        /*
                         * Otherwise, add it to the list, and drop all the rest.
@@ -1555,7 +1583,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                }
 
                /* Simplify the default result */
-               defresult = eval_const_expressions_mutator(caseexpr->defresult,
+               defresult = eval_const_expressions_mutator((Node *) caseexpr->defresult,
                                                                                                   active_fns);
 
                /*
@@ -1569,7 +1597,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                newcase->casetype = caseexpr->casetype;
                newcase->arg = NULL;
                newcase->args = newargs;
-               newcase->defresult = defresult;
+               newcase->defresult = (Expr *) defresult;
                return (Node *) newcase;
        }
 
@@ -1585,19 +1613,18 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 }
 
 /*
- * Subroutine for eval_const_expressions: try to simplify an op or func
+ * Subroutine for eval_const_expressions: try to simplify a function call
+ * (which might originally have been an operator; we don't care)
  *
- * Inputs are the op or func Expr node, and the pre-simplified argument list;
+ * Inputs are the function OID and the pre-simplified argument list;
  * also a list of already-active inline function expansions.
  *
  * Returns a simplified expression if successful, or NULL if cannot
- * simplify the op/func.
+ * simplify the function call.
  */
 static Expr *
-simplify_op_or_func(Expr *expr, List *args, bool allow_inline,
-                                       List *active_fns)
+simplify_function(Oid funcid, List *args, bool allow_inline, List *active_fns)
 {
-       Oid                     funcid;
        HeapTuple       func_tuple;
        Expr       *newexpr;
 
@@ -1609,30 +1636,16 @@ simplify_op_or_func(Expr *expr, List *args, bool allow_inline,
         * to the function's pg_proc tuple, so fetch it just once to use in both
         * attempts.
         */
-       if (expr->opType == FUNC_EXPR)
-       {
-               Func       *func = (Func *) expr->oper;
-
-               funcid = func->funcid;
-       }
-       else                                            /* OP_EXPR or DISTINCT_EXPR */
-       {
-               Oper       *oper = (Oper *) expr->oper;
-
-               replace_opid(oper);             /* OK to scribble on input to this extent */
-               funcid = oper->opid;
-       }
-
        func_tuple = SearchSysCache(PROCOID,
                                                                ObjectIdGetDatum(funcid),
                                                                0, 0, 0);
        if (!HeapTupleIsValid(func_tuple))
                elog(ERROR, "Function OID %u does not exist", funcid);
 
-       newexpr = evaluate_op_or_func(expr, args, func_tuple);
+       newexpr = evaluate_function(funcid, args, func_tuple);
 
        if (!newexpr && allow_inline)
-               newexpr = inline_op_or_func(expr, args, func_tuple, active_fns);
+               newexpr = inline_function(funcid, args, func_tuple, active_fns);
 
        ReleaseSysCache(func_tuple);
 
@@ -1640,17 +1653,17 @@ simplify_op_or_func(Expr *expr, List *args, bool allow_inline,
 }
 
 /*
- * evaluate_op_or_func: try to pre-evaluate an op or func
+ * evaluate_function: try to pre-evaluate a function call
  *
  * We can do this if the function is strict and has any constant-null inputs
  * (just return a null constant), or if the function is immutable and has all
  * constant inputs (call it and return the result as a Const node).
  *
  * Returns a simplified expression if successful, or NULL if cannot
- * simplify the op/func.
+ * simplify the function.
  */
 static Expr *
-evaluate_op_or_func(Expr *expr, List *args, HeapTuple func_tuple)
+evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
 {
        Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
        Oid                     result_typeid = funcform->prorettype;
@@ -1658,7 +1671,7 @@ evaluate_op_or_func(Expr *expr, List *args, HeapTuple func_tuple)
        bool            resultTypByVal;
        bool            has_nonconst_input = false;
        bool            has_null_input = false;
-       Expr       *newexpr;
+       FuncExpr   *newexpr;
        ExprContext *econtext;
        Datum           const_val;
        bool            const_is_null;
@@ -1705,21 +1718,20 @@ evaluate_op_or_func(Expr *expr, List *args, HeapTuple func_tuple)
         * We use the executor's routine ExecEvalExpr() to avoid duplication of
         * code and ensure we get the same result as the executor would get.
         *
-        * Build a new Expr node containing the already-simplified arguments.
-        * The only other setup needed here is the replace_opid() that
-        * simplify_op_or_func already did for the OP_EXPR/DISTINCT_EXPR case.
+        * Build a new FuncExpr node containing the already-simplified arguments.
         */
-       newexpr = makeNode(Expr);
-       newexpr->typeOid = expr->typeOid;
-       newexpr->opType = expr->opType;
-       newexpr->oper = expr->oper;
+       newexpr = makeNode(FuncExpr);
+       newexpr->funcid = funcid;
+       newexpr->funcresulttype = result_typeid;
+       newexpr->funcretset = false;
+       newexpr->funcformat = COERCE_EXPLICIT_CALL;     /* doesn't matter */
        newexpr->args = args;
 
        /* Get info needed about result datatype */
        get_typlenbyval(result_typeid, &resultTypLen, &resultTypByVal);
 
        /*
-        * It is OK to pass a dummy econtext because none of the
+        * It is OK to use a dummy econtext because none of the
         * ExecEvalExpr() code used in this situation will use econtext.  That
         * might seem fortuitous, but it's not so unreasonable --- a constant
         * expression does not depend on context, by definition, n'est ce pas?
@@ -1745,7 +1757,7 @@ evaluate_op_or_func(Expr *expr, List *args, HeapTuple func_tuple)
 }
 
 /*
- * inline_op_or_func: try to expand inline an op or func
+ * inline_function: try to expand a function call inline
  *
  * If the function is a sufficiently simple SQL-language function
  * (just "SELECT expression"), then we can inline it and avoid the rather
@@ -1763,14 +1775,13 @@ evaluate_op_or_func(Expr *expr, List *args, HeapTuple func_tuple)
  * functions by inlining them.
  *
  * Returns a simplified expression if successful, or NULL if cannot
- * simplify the op/func.
+ * simplify the function.
  */
 static Expr *
-inline_op_or_func(Expr *expr, List *args, HeapTuple func_tuple,
-                                 List *active_fns)
+inline_function(Oid funcid, List *args, HeapTuple func_tuple,
+                               List *active_fns)
 {
        Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
-       Oid                     funcid = HeapTupleGetOid(func_tuple);
        Oid                     result_typeid = funcform->prorettype;
        char            result_typtype;
        char       *src;
@@ -1816,7 +1827,7 @@ inline_op_or_func(Expr *expr, List *args, HeapTuple func_tuple,
         * stuff that parsing might create.
         */
        mycxt = AllocSetContextCreate(CurrentMemoryContext,
-                                                                 "inline_op_or_func",
+                                                                 "inline_function",
                                                                  ALLOCSET_DEFAULT_MINSIZE,
                                                                  ALLOCSET_DEFAULT_INITSIZE,
                                                                  ALLOCSET_DEFAULT_MAXSIZE);
@@ -1828,7 +1839,7 @@ inline_op_or_func(Expr *expr, List *args, HeapTuple func_tuple,
                                                  Anum_pg_proc_prosrc,
                                                  &isNull);
        if (isNull)
-               elog(ERROR, "inline_op_or_func: null prosrc for procedure %u",
+               elog(ERROR, "inline_function: null prosrc for procedure %u",
                         funcid);
        src = DatumGetCString(DirectFunctionCall1(textout, tmp));
 
@@ -1877,7 +1888,7 @@ inline_op_or_func(Expr *expr, List *args, HeapTuple func_tuple,
                length(querytree->targetList) != 1)
                goto fail;
 
-       newexpr = ((TargetEntry *) lfirst(querytree->targetList))->expr;
+       newexpr = (Node *) ((TargetEntry *) lfirst(querytree->targetList))->expr;
 
        /*
         * Additional validity checks on the expression.  It mustn't return a
@@ -2065,17 +2076,17 @@ substitute_actual_parameters_mutator(Node *node,
  * FromExpr, JoinExpr, and SetOperationStmt nodes are handled, so that query
  * jointrees and setOperation trees can be processed without additional code.
  *
- * expression_tree_walker will handle SubLink and SubPlan nodes by recursing
- * normally into the "lefthand" arguments (which belong to the outer plan).
- * It will also call the walker on the sub-Query node; however, when
- * expression_tree_walker itself is called on a Query node, it does nothing
- * and returns "false".  The net effect is that unless the walker does
- * something special at a Query node, sub-selects will not be visited
- * during an expression tree walk.     This is exactly the behavior wanted
- * in many cases --- and for those walkers that do want to recurse into
- * sub-selects, special behavior is typically needed anyway at the entry
- * to a sub-select (such as incrementing a depth counter).     A walker that
- * wants to examine sub-selects should include code along the lines of:
+ * expression_tree_walker will handle SubLink and SubPlanExpr nodes by
+ * recursing normally into the "lefthand" arguments (which are expressions
+ * belonging to the outer plan).  It will also call the walker on the
+ * sub-Query node; however, when expression_tree_walker itself is called on a
+ * Query node, it does nothing and returns "false".  The net effect is that
+ * unless the walker does something special at a Query node, sub-selects will
+ * not be visited during an expression tree walk. This is exactly the behavior
+ * wanted in many cases --- and for those walkers that do want to recurse into
+ * sub-selects, special behavior is typically needed anyway at the entry to a
+ * sub-select (such as incrementing a depth counter). A walker that wants to
+ * examine sub-selects should include code along the lines of:
  *
  *             if (IsA(node, Query))
  *             {
@@ -2115,29 +2126,12 @@ expression_tree_walker(Node *node,
                return false;
        switch (nodeTag(node))
        {
-               case T_Const:
                case T_Var:
+               case T_Const:
                case T_Param:
                case T_RangeTblRef:
                        /* primitive node types with no subnodes */
                        break;
-               case T_Expr:
-                       {
-                               Expr       *expr = (Expr *) node;
-
-                               if (expr->opType == SUBPLAN_EXPR)
-                               {
-                                       /* recurse to the SubLink node (skipping SubPlan!) */
-                                       if (walker((Node *) ((SubPlan *) expr->oper)->sublink,
-                                                          context))
-                                               return true;
-                               }
-                               /* for all Expr node types, examine args list */
-                               if (expression_tree_walker((Node *) expr->args,
-                                                                                  walker, context))
-                                       return true;
-                       }
-                       break;
                case T_Aggref:
                        return walker(((Aggref *) node)->target, context);
                case T_ArrayRef:
@@ -2158,41 +2152,41 @@ expression_tree_walker(Node *node,
                                        return true;
                        }
                        break;
-               case T_FieldSelect:
-                       return walker(((FieldSelect *) node)->arg, context);
-               case T_RelabelType:
-                       return walker(((RelabelType *) node)->arg, context);
-               case T_CaseExpr:
+               case T_FuncExpr:
                        {
-                               CaseExpr   *caseexpr = (CaseExpr *) node;
+                               FuncExpr   *expr = (FuncExpr *) node;
 
-                               /* we assume walker doesn't care about CaseWhens, either */
-                               foreach(temp, caseexpr->args)
-                               {
-                                       CaseWhen   *when = (CaseWhen *) lfirst(temp);
+                               if (expression_tree_walker((Node *) expr->args,
+                                                                                  walker, context))
+                                       return true;
+                       }
+                       break;
+               case T_OpExpr:
+                       {
+                               OpExpr     *expr = (OpExpr *) node;
 
-                                       Assert(IsA(when, CaseWhen));
-                                       if (walker(when->expr, context))
-                                               return true;
-                                       if (walker(when->result, context))
-                                               return true;
-                               }
-                               /* caseexpr->arg should be null, but we'll check it anyway */
-                               if (walker(caseexpr->arg, context))
+                               if (expression_tree_walker((Node *) expr->args,
+                                                                                  walker, context))
                                        return true;
-                               if (walker(caseexpr->defresult, context))
+                       }
+                       break;
+               case T_DistinctExpr:
+                       {
+                               DistinctExpr *expr = (DistinctExpr *) node;
+
+                               if (expression_tree_walker((Node *) expr->args,
+                                                                                  walker, context))
                                        return true;
                        }
                        break;
-               case T_NullTest:
-                       return walker(((NullTest *) node)->arg, context);
-               case T_BooleanTest:
-                       return walker(((BooleanTest *) node)->arg, context);
-               case T_ConstraintTest:
-                       if (walker(((ConstraintTest *) node)->arg, context))
-                               return true;
-                       return walker(((ConstraintTest *) node)->check_expr, context);
-               case T_ConstraintTestValue:
+               case T_BoolExpr:
+                       {
+                               BoolExpr   *expr = (BoolExpr *) node;
+
+                               if (expression_tree_walker((Node *) expr->args,
+                                                                                  walker, context))
+                                       return true;
+                       }
                        break;
                case T_SubLink:
                        {
@@ -2202,7 +2196,7 @@ expression_tree_walker(Node *node,
                                 * If the SubLink has already been processed by
                                 * subselect.c, it will have lefthand=NIL, and we need to
                                 * scan the oper list.  Otherwise we only need to look at
-                                * the lefthand list (the incomplete Oper nodes in the
+                                * the lefthand list (the incomplete OpExpr nodes in the
                                 * oper list are deemed uninteresting, perhaps even
                                 * confusing).
                                 */
@@ -2224,6 +2218,57 @@ expression_tree_walker(Node *node,
                                return walker(sublink->subselect, context);
                        }
                        break;
+               case T_SubPlanExpr:
+                       {
+                               SubPlanExpr *expr = (SubPlanExpr *) node;
+
+                               /* recurse to the SubLink node, but not into the Plan */
+                               if (walker((Node *) expr->sublink, context))
+                                       return true;
+                               /* also examine args list */
+                               if (expression_tree_walker((Node *) expr->args,
+                                                                                  walker, context))
+                                       return true;
+                       }
+                       break;
+               case T_FieldSelect:
+                       return walker(((FieldSelect *) node)->arg, context);
+               case T_RelabelType:
+                       return walker(((RelabelType *) node)->arg, context);
+               case T_CaseExpr:
+                       {
+                               CaseExpr   *caseexpr = (CaseExpr *) node;
+
+                               /* we assume walker doesn't care about CaseWhens, either */
+                               foreach(temp, caseexpr->args)
+                               {
+                                       CaseWhen   *when = (CaseWhen *) lfirst(temp);
+
+                                       Assert(IsA(when, CaseWhen));
+                                       if (walker(when->expr, context))
+                                               return true;
+                                       if (walker(when->result, context))
+                                               return true;
+                               }
+                               /* caseexpr->arg should be null, but we'll check it anyway */
+                               if (walker(caseexpr->arg, context))
+                                       return true;
+                               if (walker(caseexpr->defresult, context))
+                                       return true;
+                       }
+                       break;
+               case T_NullTest:
+                       return walker(((NullTest *) node)->arg, context);
+               case T_BooleanTest:
+                       return walker(((BooleanTest *) node)->arg, context);
+               case T_ConstraintTest:
+                       if (walker(((ConstraintTest *) node)->arg, context))
+                               return true;
+                       return walker(((ConstraintTest *) node)->check_expr, context);
+               case T_ConstraintTestValue:
+                       break;
+               case T_TargetEntry:
+                       return walker(((TargetEntry *) node)->expr, context);
                case T_Query:
                        /* Do nothing with a sub-Query, per discussion above */
                        break;
@@ -2234,8 +2279,6 @@ expression_tree_walker(Node *node,
                                        return true;
                        }
                        break;
-               case T_TargetEntry:
-                       return walker(((TargetEntry *) node)->expr, context);
                case T_FromExpr:
                        {
                                FromExpr   *from = (FromExpr *) node;
@@ -2387,14 +2430,14 @@ query_tree_walker(Query *query,
  * expression_tree_mutator include all those normally found in target lists
  * and qualifier clauses during the planning stage.
  *
- * expression_tree_mutator will handle a SUBPLAN_EXPR node by recursing into
- * the args and slink->oper lists (which belong to the outer plan), but it
+ * expression_tree_mutator will handle a SubPlanExpr node by recursing into
+ * the args and sublink->oper lists (which belong to the outer plan), but it
  * will simply copy the link to the inner plan, since that's typically what
  * expression tree mutators want.  A mutator that wants to modify the subplan
  * can force appropriate behavior by recognizing subplan expression nodes
  * and doing the right thing.
  *
- * Bare SubLink nodes (without a SUBPLAN_EXPR) are handled by recursing into
+ * Bare SubLink nodes (without a SubPlanExpr) are handled by recursing into
  * the "lefthand" argument list only.  (A bare SubLink should be seen only if
  * the tree has not yet been processed by subselect.c.)  Again, this can be
  * overridden by the mutator, but it seems to be the most useful default
@@ -2428,61 +2471,19 @@ expression_tree_mutator(Node *node,
                return NULL;
        switch (nodeTag(node))
        {
-               case T_Const:
                case T_Var:
+               case T_Const:
                case T_Param:
                case T_RangeTblRef:
                        /* primitive node types with no subnodes */
                        return (Node *) copyObject(node);
-               case T_Expr:
-                       {
-                               Expr       *expr = (Expr *) node;
-                               Expr       *newnode;
-
-                               FLATCOPY(newnode, expr, Expr);
-
-                               if (expr->opType == SUBPLAN_EXPR)
-                               {
-                                       SubLink    *oldsublink = ((SubPlan *) expr->oper)->sublink;
-                                       SubPlan    *newsubplan;
-
-                                       /* flat-copy the oper node, which is a SubPlan */
-                                       CHECKFLATCOPY(newsubplan, expr->oper, SubPlan);
-                                       newnode->oper = (Node *) newsubplan;
-                                       /* likewise its SubLink node */
-                                       CHECKFLATCOPY(newsubplan->sublink, oldsublink, SubLink);
-
-                                       /*
-                                        * transform args list (params to be passed to
-                                        * subplan)
-                                        */
-                                       MUTATE(newnode->args, expr->args, List *);
-                                       /* transform sublink's oper list as well */
-                                       MUTATE(newsubplan->sublink->oper, oldsublink->oper, List *);
-
-                                       /*
-                                        * but not the subplan itself, which is referenced
-                                        * as-is
-                                        */
-                               }
-                               else
-                               {
-                                       /*
-                                        * for other Expr node types, just transform args
-                                        * list, linking to original oper node (OK?)
-                                        */
-                                       MUTATE(newnode->args, expr->args, List *);
-                               }
-                               return (Node *) newnode;
-                       }
-                       break;
                case T_Aggref:
                        {
                                Aggref     *aggref = (Aggref *) node;
                                Aggref     *newnode;
 
                                FLATCOPY(newnode, aggref, Aggref);
-                               MUTATE(newnode->target, aggref->target, Node *);
+                               MUTATE(newnode->target, aggref->target, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2497,9 +2498,81 @@ expression_tree_mutator(Node *node,
                                MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr,
                                           List *);
                                MUTATE(newnode->refexpr, arrayref->refexpr,
-                                          Node *);
+                                          Expr *);
                                MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr,
-                                          Node *);
+                                          Expr *);
+                               return (Node *) newnode;
+                       }
+                       break;
+               case T_FuncExpr:
+                       {
+                               FuncExpr   *expr = (FuncExpr *) node;
+                               FuncExpr   *newnode;
+
+                               FLATCOPY(newnode, expr, FuncExpr);
+                               MUTATE(newnode->args, expr->args, List *);
+                               return (Node *) newnode;
+                       }
+                       break;
+               case T_OpExpr:
+                       {
+                               OpExpr     *expr = (OpExpr *) node;
+                               OpExpr     *newnode;
+
+                               FLATCOPY(newnode, expr, OpExpr);
+                               MUTATE(newnode->args, expr->args, List *);
+                               return (Node *) newnode;
+                       }
+                       break;
+               case T_DistinctExpr:
+                       {
+                               DistinctExpr   *expr = (DistinctExpr *) node;
+                               DistinctExpr   *newnode;
+
+                               FLATCOPY(newnode, expr, DistinctExpr);
+                               MUTATE(newnode->args, expr->args, List *);
+                               return (Node *) newnode;
+                       }
+                       break;
+               case T_BoolExpr:
+                       {
+                               BoolExpr   *expr = (BoolExpr *) node;
+                               BoolExpr   *newnode;
+
+                               FLATCOPY(newnode, expr, BoolExpr);
+                               MUTATE(newnode->args, expr->args, List *);
+                               return (Node *) newnode;
+                       }
+                       break;
+               case T_SubLink:
+                       {
+                               /*
+                                * A "bare" SubLink (note we will not come here if we
+                                * found a SubPlanExpr node above it).  Transform the
+                                * lefthand side, but not the oper list nor the subquery.
+                                */
+                               SubLink    *sublink = (SubLink *) node;
+                               SubLink    *newnode;
+
+                               FLATCOPY(newnode, sublink, SubLink);
+                               MUTATE(newnode->lefthand, sublink->lefthand, List *);
+                               return (Node *) newnode;
+                       }
+                       break;
+               case T_SubPlanExpr:
+                       {
+                               SubPlanExpr   *expr = (SubPlanExpr *) node;
+                               SubLink           *oldsublink = expr->sublink;
+                               SubPlanExpr   *newnode;
+
+                               FLATCOPY(newnode, expr, SubPlanExpr);
+                               /* flat-copy the SubLink node */
+                               CHECKFLATCOPY(newnode->sublink, oldsublink, SubLink);
+                               /* transform args list (params to be passed to subplan) */
+                               MUTATE(newnode->args, expr->args, List *);
+                               /* transform sublink's oper list as well */
+                               MUTATE(newnode->sublink->oper, oldsublink->oper, List *);
+                               /* but not the subplan itself, which is referenced as-is */
                                return (Node *) newnode;
                        }
                        break;
@@ -2509,7 +2582,7 @@ expression_tree_mutator(Node *node,
                                FieldSelect *newnode;
 
                                FLATCOPY(newnode, fselect, FieldSelect);
-                               MUTATE(newnode->arg, fselect->arg, Node *);
+                               MUTATE(newnode->arg, fselect->arg, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2519,7 +2592,7 @@ expression_tree_mutator(Node *node,
                                RelabelType *newnode;
 
                                FLATCOPY(newnode, relabel, RelabelType);
-                               MUTATE(newnode->arg, relabel->arg, Node *);
+                               MUTATE(newnode->arg, relabel->arg, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2531,8 +2604,8 @@ expression_tree_mutator(Node *node,
                                FLATCOPY(newnode, caseexpr, CaseExpr);
                                MUTATE(newnode->args, caseexpr->args, List *);
                                /* caseexpr->arg should be null, but we'll check it anyway */
-                               MUTATE(newnode->arg, caseexpr->arg, Node *);
-                               MUTATE(newnode->defresult, caseexpr->defresult, Node *);
+                               MUTATE(newnode->arg, caseexpr->arg, Expr *);
+                               MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2542,8 +2615,8 @@ expression_tree_mutator(Node *node,
                                CaseWhen   *newnode;
 
                                FLATCOPY(newnode, casewhen, CaseWhen);
-                               MUTATE(newnode->expr, casewhen->expr, Node *);
-                               MUTATE(newnode->result, casewhen->result, Node *);
+                               MUTATE(newnode->expr, casewhen->expr, Expr *);
+                               MUTATE(newnode->result, casewhen->result, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2553,7 +2626,7 @@ expression_tree_mutator(Node *node,
                                NullTest   *newnode;
 
                                FLATCOPY(newnode, ntest, NullTest);
-                               MUTATE(newnode->arg, ntest->arg, Node *);
+                               MUTATE(newnode->arg, ntest->arg, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2563,7 +2636,7 @@ expression_tree_mutator(Node *node,
                                BooleanTest *newnode;
 
                                FLATCOPY(newnode, btest, BooleanTest);
-                               MUTATE(newnode->arg, btest->arg, Node *);
+                               MUTATE(newnode->arg, btest->arg, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2573,8 +2646,8 @@ expression_tree_mutator(Node *node,
                                ConstraintTest *newnode;
 
                                FLATCOPY(newnode, ctest, ConstraintTest);
-                               MUTATE(newnode->arg, ctest->arg, Node *);
-                               MUTATE(newnode->check_expr, ctest->check_expr, Node *);
+                               MUTATE(newnode->arg, ctest->arg, Expr *);
+                               MUTATE(newnode->check_expr, ctest->check_expr, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2587,18 +2660,17 @@ expression_tree_mutator(Node *node,
                                return (Node *) newnode;
                        }
                        break;
-               case T_SubLink:
+               case T_TargetEntry:
                        {
                                /*
-                                * A "bare" SubLink (note we will not come here if we
-                                * found a SUBPLAN_EXPR node above it).  Transform the
-                                * lefthand side, but not the oper list nor the subquery.
+                                * We mutate the expression, but not the resdom, by
+                                * default.
                                 */
-                               SubLink    *sublink = (SubLink *) node;
-                               SubLink    *newnode;
+                               TargetEntry *targetentry = (TargetEntry *) node;
+                               TargetEntry *newnode;
 
-                               FLATCOPY(newnode, sublink, SubLink);
-                               MUTATE(newnode->lefthand, sublink->lefthand, List *);
+                               FLATCOPY(newnode, targetentry, TargetEntry);
+                               MUTATE(newnode->expr, targetentry->expr, Expr *);
                                return (Node *) newnode;
                        }
                        break;
@@ -2622,20 +2694,6 @@ expression_tree_mutator(Node *node,
                                return (Node *) resultlist;
                        }
                        break;
-               case T_TargetEntry:
-                       {
-                               /*
-                                * We mutate the expression, but not the resdom, by
-                                * default.
-                                */
-                               TargetEntry *targetentry = (TargetEntry *) node;
-                               TargetEntry *newnode;
-
-                               FLATCOPY(newnode, targetentry, TargetEntry);
-                               MUTATE(newnode->expr, targetentry->expr, Node *);
-                               return (Node *) newnode;
-                       }
-                       break;
                case T_FromExpr:
                        {
                                FromExpr   *from = (FromExpr *) node;
index fa8c898..0d268b8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.52 2002/06/20 20:29:31 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.53 2002/12/12 15:49:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -110,7 +110,7 @@ create_tl_element(Var *var, int resdomno)
                                                                          var->vartypmod,
                                                                          NULL,
                                                                          false),
-                                                  (Node *) var);
+                                                  (Expr *) var);
 }
 
 /*****************************************************************************
@@ -253,5 +253,5 @@ get_sortgroupclause_expr(SortClause *sortClause, List *targetList)
 {
        TargetEntry *tle = get_sortgroupclause_tle(sortClause, targetList);
 
-       return tle->expr;
+       return (Node *) tle->expr;
 }
index 23b824d..8d22aa2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.40 2002/09/11 14:48:54 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.41 2002/12/12 15:49:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -65,7 +65,7 @@ static Node *flatten_join_alias_vars_mutator(Node *node,
  * NOTE: this is used on not-yet-planned expressions.  It may therefore find
  * bare SubLinks, and if so it needs to recurse into them to look for uplevel
  * references to the desired rtable level!     But when we find a completed
- * SubPlan, we only need to look at the parameters passed to the subplan.
+ * SubPlanExpr, we only need to look at the parameters passed to the subplan.
  */
 List *
 pull_varnos(Node *node)
@@ -111,12 +111,12 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
                 * executed by the outer query.  But short-circuit recursion into
                 * the subquery itself, which would be a waste of effort.
                 */
-               Expr       *expr = (Expr *) node;
+               SubPlanExpr *subplan = (SubPlanExpr *) node;
 
-               if (pull_varnos_walker((Node *) ((SubPlan *) expr->oper)->sublink->oper,
+               if (pull_varnos_walker((Node *) subplan->sublink->oper,
                                                           context))
                        return true;
-               if (pull_varnos_walker((Node *) expr->args,
+               if (pull_varnos_walker((Node *) subplan->args,
                                                           context))
                        return true;
                return false;
@@ -146,7 +146,7 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
  * NOTE: this is used on not-yet-planned expressions.  It may therefore find
  * bare SubLinks, and if so it needs to recurse into them to look for uplevel
  * references to the desired rtable entry!     But when we find a completed
- * SubPlan, we only need to look at the parameters passed to the subplan.
+ * SubPlanExpr, we only need to look at the parameters passed to the subplan.
  */
 bool
 contain_var_reference(Node *node, int varno, int varattno, int levelsup)
@@ -194,12 +194,12 @@ contain_var_reference_walker(Node *node,
                 * executed by the outer query.  But short-circuit recursion into
                 * the subquery itself, which would be a waste of effort.
                 */
-               Expr       *expr = (Expr *) node;
+               SubPlanExpr *subplan = (SubPlanExpr *) node;
 
-               if (contain_var_reference_walker((Node *) ((SubPlan *) expr->oper)->sublink->oper,
+               if (contain_var_reference_walker((Node *) subplan->sublink->oper,
                                                                                 context))
                        return true;
-               if (contain_var_reference_walker((Node *) expr->args,
+               if (contain_var_reference_walker((Node *) subplan->args,
                                                                                 context))
                        return true;
                return false;
index 18144f7..56f0fdd 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.254 2002/11/15 02:50:07 momjian Exp $
+ *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.255 2002/12/12 15:49:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -479,14 +479,14 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
                {
                        TargetEntry *tle = (TargetEntry *) lfirst(tl);
                        Resdom     *resnode = tle->resdom;
-                       Node       *expr;
+                       Expr       *expr;
 
                        if (resnode->resjunk)
                                continue;
                        if (tle->expr && IsA(tle->expr, Const))
                                expr = tle->expr;
                        else
-                               expr = (Node *) makeVar(rtr->rtindex,
+                               expr = (Expr *) makeVar(rtr->rtindex,
                                                                                resnode->resno,
                                                                                resnode->restype,
                                                                                resnode->restypmod,
@@ -1807,14 +1807,14 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
                Resdom     *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
                char       *colName = pstrdup(leftResdom->resname);
                Resdom     *resdom;
-               Node       *expr;
+               Expr       *expr;
 
                resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
                                                        colType,
                                                        -1,
                                                        colName,
                                                        false);
-               expr = (Node *) makeVar(1,
+               expr = (Expr *) makeVar(1,
                                                                leftResdom->resno,
                                                                colType,
                                                                -1,
@@ -2424,7 +2424,7 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
                                         format_type_be(given_type_id),
                                         format_type_be(expected_type_id));
 
-                       fix_opids(expr);
+                       fix_opfuncids(expr);
 
                        lfirst(l) = expr;
 
index b3edb3b..53e1a59 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.386 2002/12/06 05:00:22 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.387 2002/12/12 15:49:36 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -5755,70 +5755,70 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                        | a_expr ISNULL
                                {
                                        NullTest *n = makeNode(NullTest);
-                                       n->arg = $1;
+                                       n->arg = (Expr *) $1;
                                        n->nulltesttype = IS_NULL;
                                        $$ = (Node *)n;
                                }
                        | a_expr IS NULL_P
                                {
                                        NullTest *n = makeNode(NullTest);
-                                       n->arg = $1;
+                                       n->arg = (Expr *) $1;
                                        n->nulltesttype = IS_NULL;
                                        $$ = (Node *)n;
                                }
                        | a_expr NOTNULL
                                {
                                        NullTest *n = makeNode(NullTest);
-                                       n->arg = $1;
+                                       n->arg = (Expr *) $1;
                                        n->nulltesttype = IS_NOT_NULL;
                                        $$ = (Node *)n;
                                }
                        | a_expr IS NOT NULL_P
                                {
                                        NullTest *n = makeNode(NullTest);
-                                       n->arg = $1;
+                                       n->arg = (Expr *) $1;
                                        n->nulltesttype = IS_NOT_NULL;
                                        $$ = (Node *)n;
                                }
                        | a_expr IS TRUE_P
                                {
                                        BooleanTest *b = makeNode(BooleanTest);
-                                       b->arg = $1;
+                                       b->arg = (Expr *) $1;
                                        b->booltesttype = IS_TRUE;
                                        $$ = (Node *)b;
                                }
                        | a_expr IS NOT TRUE_P
                                {
                                        BooleanTest *b = makeNode(BooleanTest);
-                                       b->arg = $1;
+                                       b->arg = (Expr *) $1;
                                        b->booltesttype = IS_NOT_TRUE;
                                        $$ = (Node *)b;
                                }
                        | a_expr IS FALSE_P
                                {
                                        BooleanTest *b = makeNode(BooleanTest);
-                                       b->arg = $1;
+                                       b->arg = (Expr *) $1;
                                        b->booltesttype = IS_FALSE;
                                        $$ = (Node *)b;
                                }
                        | a_expr IS NOT FALSE_P
                                {
                                        BooleanTest *b = makeNode(BooleanTest);
-                                       b->arg = $1;
+                                       b->arg = (Expr *) $1;
                                        b->booltesttype = IS_NOT_FALSE;
                                        $$ = (Node *)b;
                                }
                        | a_expr IS UNKNOWN
                                {
                                        BooleanTest *b = makeNode(BooleanTest);
-                                       b->arg = $1;
+                                       b->arg = (Expr *) $1;
                                        b->booltesttype = IS_UNKNOWN;
                                        $$ = (Node *)b;
                                }
                        | a_expr IS NOT UNKNOWN
                                {
                                        BooleanTest *b = makeNode(BooleanTest);
-                                       b->arg = $1;
+                                       b->arg = (Expr *) $1;
                                        b->booltesttype = IS_NOT_UNKNOWN;
                                        $$ = (Node *)b;
                                }
@@ -6640,9 +6640,9 @@ in_expr:  select_with_parens
 case_expr:     CASE case_arg when_clause_list case_default END_TRANS
                                {
                                        CaseExpr *c = makeNode(CaseExpr);
-                                       c->arg = $2;
+                                       c->arg = (Expr *) $2;
                                        c->args = $3;
-                                       c->defresult = $4;
+                                       c->defresult = (Expr *) $4;
                                        $$ = (Node *)c;
                                }
                        | NULLIF '(' a_expr ',' a_expr ')'
@@ -6650,10 +6650,10 @@ case_expr:      CASE case_arg when_clause_list case_default END_TRANS
                                        CaseExpr *c = makeNode(CaseExpr);
                                        CaseWhen *w = makeNode(CaseWhen);
 
-                                       w->expr = (Node *) makeSimpleA_Expr(OP, "=", $3, $5);
+                                       w->expr = (Expr *) makeSimpleA_Expr(OP, "=", $3, $5);
                                        /* w->result is left NULL */
                                        c->args = makeList1(w);
-                                       c->defresult = $3;
+                                       c->defresult = (Expr *) $3;
                                        $$ = (Node *)c;
                                }
                        | COALESCE '(' expr_list ')'
@@ -6666,7 +6666,7 @@ case_expr:        CASE case_arg when_clause_list case_default END_TRANS
                                                NullTest *n = makeNode(NullTest);
                                                n->arg = lfirst(l);
                                                n->nulltesttype = IS_NOT_NULL;
-                                               w->expr = (Node *) n;
+                                               w->expr = (Expr *) n;
                                                w->result = lfirst(l);
                                                c->args = lappend(c->args, w);
                                        }
@@ -6684,8 +6684,8 @@ when_clause:
                        WHEN a_expr THEN a_expr
                                {
                                        CaseWhen *w = makeNode(CaseWhen);
-                                       w->expr = $2;
-                                       w->result = $4;
+                                       w->expr = (Expr *) $2;
+                                       w->result = (Expr *) $4;
                                        $$ = (Node *)w;
                                }
                ;
@@ -7594,20 +7594,17 @@ static Node *
 makeRowNullTest(NullTestType test, List *args)
 {
        Node *expr = NULL;
-       Node *arg;
        NullTest *n;
 
        if (lnext(args) != NIL)
                expr = makeRowNullTest(test, lnext(args));
 
-       arg = lfirst(args);
-
        n = makeNode(NullTest);
-       n->arg = arg;
+       n->arg = (Expr *) lfirst(args);
        n->nulltesttype = test;
 
        if (expr == NULL)
-               expr = (Node *)n;
+               expr = (Node *) n;
        else if (test == IS_NOT_NULL)
                expr = (Node *) makeA_Expr(OR, NIL, expr, (Node *)n);
        else
index ca398b4..6f05ee3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.100 2002/11/29 21:39:11 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.101 2002/12/12 15:49:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -503,17 +503,6 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
        }
 
        /*
-        * Insist we have a bare function call (explain.c is the only place
-        * that depends on this, I think).      If this fails, it's probably
-        * because transformExpr interpreted the function notation as a type
-        * coercion.
-        */
-       if (!funcexpr ||
-               !IsA(funcexpr, Expr) ||
-               ((Expr *) funcexpr)->opType != FUNC_EXPR)
-               elog(ERROR, "Coercion function not allowed in FROM clause");
-
-       /*
         * OK, build an RTE for the function.
         */
        rte = addRangeTableEntryForFunction(pstate, funcname, funcexpr,
@@ -876,7 +865,7 @@ buildMergedJoinVar(JoinType jointype, Var *l_colvar, Var *r_colvar)
                                                         outcoltype,
                                                         COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
        else if (l_colvar->vartypmod != outcoltypmod)
-               l_node = (Node *) makeRelabelType((Node *) l_colvar,
+               l_node = (Node *) makeRelabelType((Expr *) l_colvar,
                                                                                  outcoltype, outcoltypmod,
                                                                                  COERCE_IMPLICIT_CAST);
        else
@@ -887,7 +876,7 @@ buildMergedJoinVar(JoinType jointype, Var *l_colvar, Var *r_colvar)
                                                         outcoltype,
                                                         COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
        else if (r_colvar->vartypmod != outcoltypmod)
-               r_node = (Node *) makeRelabelType((Node *) r_colvar,
+               r_node = (Node *) makeRelabelType((Expr *) r_colvar,
                                                                                  outcoltype, outcoltypmod,
                                                                                  COERCE_IMPLICIT_CAST);
        else
@@ -928,13 +917,13 @@ buildMergedJoinVar(JoinType jointype, Var *l_colvar, Var *r_colvar)
                                CaseWhen   *w = makeNode(CaseWhen);
                                NullTest   *n = makeNode(NullTest);
 
-                               n->arg = l_node;
+                               n->arg = (Expr *) l_node;
                                n->nulltesttype = IS_NOT_NULL;
-                               w->expr = (Node *) n;
-                               w->result = l_node;
+                               w->expr = (Expr *) n;
+                               w->result = (Expr *) l_node;
                                c->casetype = outcoltype;
                                c->args = makeList1(w);
-                               c->defresult = r_node;
+                               c->defresult = (Expr *) r_node;
                                res_node = (Node *) c;
                                break;
                        }
index 6d3524c..3856939 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.89 2002/11/30 18:28:49 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.90 2002/12/12 15:49:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -88,7 +88,8 @@ coerce_to_target_type(Node *expr, Oid exprtype,
                                                           ccontext, cformat);
                        /* Need a RelabelType if no typmod coercion is performed */
                        if (targettypmod < 0)
-                               expr = (Node *) makeRelabelType(expr, targettype, -1,
+                               expr = (Node *) makeRelabelType((Expr *) expr,
+                                                                                               targettype, -1,
                                                                                                cformat);
                }
                else
@@ -190,7 +191,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
                                                                                         cformat);
                        /* We might now need a RelabelType. */
                        if (exprType(result) != targetTypeId)
-                               result = (Node *) makeRelabelType(result, targetTypeId, -1,
+                               result = (Node *) makeRelabelType((Expr *) result,
+                                                                                                 targetTypeId, -1,
                                                                                                  cformat);
                }
 
@@ -227,7 +229,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
                        {
                                result = coerce_type_constraints(result, targetTypeId,
                                                                                                 cformat);
-                               result = (Node *) makeRelabelType(result, targetTypeId, -1,
+                               result = (Node *) makeRelabelType((Expr *) result,
+                                                                                                 targetTypeId, -1,
                                                                                                  cformat);
                        }
 
@@ -266,7 +269,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
                         * typmod, which is likely but not certain (wrong if target is
                         * a domain, in any case).
                         */
-                       result = (Node *) makeRelabelType(result, targetTypeId, -1,
+                       result = (Node *) makeRelabelType((Expr *) result,
+                                                                                         targetTypeId, -1,
                                                                                          cformat);
                }
        }
@@ -277,7 +281,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
                 * except relabel the type.  This is binary compatibility for
                 * complex types.
                 */
-               result = (Node *) makeRelabelType(node, targetTypeId, -1,
+               result = (Node *) makeRelabelType((Expr *) node,
+                                                                                 targetTypeId, -1,
                                                                                  cformat);
        }
        else
@@ -449,7 +454,7 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
                                elog(ERROR, "coerce_type_constraints: domain %s constraint %s has NULL conbin",
                                         NameStr(typTup->typname), NameStr(c->conname));
 
-                       r->arg = arg;
+                       r->arg = (Expr *) arg;
                        r->testtype = CONSTR_TEST_CHECK;
                        r->name = NameStr(c->conname);
                        r->domname = NameStr(typTup->typname);
@@ -492,7 +497,7 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
        {
                ConstraintTest *r = makeNode(ConstraintTest);
 
-               r->arg = arg;
+               r->arg = (Expr *) arg;
                r->testtype = CONSTR_TEST_NOTNULL;
                r->name = "NOT NULL";
                r->domname = notNull;
@@ -1140,21 +1145,14 @@ find_typmod_coercion_function(Oid typeId, int *nargs)
 static Node *
 build_func_call(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
 {
-       Func       *funcnode;
-       Expr       *expr;
-
-       funcnode = makeNode(Func);
-       funcnode->funcid = funcid;
-       funcnode->funcresulttype = rettype;
-       funcnode->funcretset = false;           /* only possible case here */
-       funcnode->funcformat = fformat;
-       funcnode->func_fcache = NULL;
-
-       expr = makeNode(Expr);
-       expr->typeOid = rettype;
-       expr->opType = FUNC_EXPR;
-       expr->oper = (Node *) funcnode;
-       expr->args = args;
-
-       return (Node *) expr;
+       FuncExpr   *funcexpr;
+
+       funcexpr = makeNode(FuncExpr);
+       funcexpr->funcid = funcid;
+       funcexpr->funcresulttype = rettype;
+       funcexpr->funcretset = false;           /* only possible case here */
+       funcexpr->funcformat = fformat;
+       funcexpr->args = args;
+
+       return (Node *) funcexpr;
 }
index 41e6694..7dcbf59 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.135 2002/12/06 05:00:26 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.136 2002/12/12 15:49:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -199,9 +199,9 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                                n->nulltesttype = IS_NULL;
 
                                                                if (exprIsNullConstant(a->lexpr))
-                                                                       n->arg = a->rexpr;
+                                                                       n->arg = (Expr *) a->rexpr;
                                                                else
-                                                                       n->arg = a->lexpr;
+                                                                       n->arg = (Expr *) a->lexpr;
 
                                                                result = transformExpr(pstate,
                                                                                                           (Node *) n, domVal);
@@ -225,15 +225,13 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                                                                                          a->lexpr, domVal);
                                                        Node       *rexpr = transformExpr(pstate,
                                                                                                                          a->rexpr, domVal);
-                                                       Expr       *expr = makeNode(Expr);
 
                                                        lexpr = coerce_to_boolean(lexpr, "AND");
                                                        rexpr = coerce_to_boolean(rexpr, "AND");
 
-                                                       expr->typeOid = BOOLOID;
-                                                       expr->opType = AND_EXPR;
-                                                       expr->args = makeList2(lexpr, rexpr);
-                                                       result = (Node *) expr;
+                                                       result = (Node *) makeBoolExpr(AND_EXPR,
+                                                                                                                  makeList2(lexpr,
+                                                                                                                                        rexpr));
                                                }
                                                break;
                                        case OR:
@@ -242,29 +240,24 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                                                                                          a->lexpr, domVal);
                                                        Node       *rexpr = transformExpr(pstate,
                                                                                                                          a->rexpr, domVal);
-                                                       Expr       *expr = makeNode(Expr);
 
                                                        lexpr = coerce_to_boolean(lexpr, "OR");
                                                        rexpr = coerce_to_boolean(rexpr, "OR");
 
-                                                       expr->typeOid = BOOLOID;
-                                                       expr->opType = OR_EXPR;
-                                                       expr->args = makeList2(lexpr, rexpr);
-                                                       result = (Node *) expr;
+                                                       result = (Node *) makeBoolExpr(OR_EXPR,
+                                                                                                                  makeList2(lexpr,
+                                                                                                                                        rexpr));
                                                }
                                                break;
                                        case NOT:
                                                {
                                                        Node       *rexpr = transformExpr(pstate,
                                                                                                                          a->rexpr, domVal);
-                                                       Expr       *expr = makeNode(Expr);
 
                                                        rexpr = coerce_to_boolean(rexpr, "NOT");
 
-                                                       expr->typeOid = BOOLOID;
-                                                       expr->opType = NOT_EXPR;
-                                                       expr->args = makeList1(rexpr);
-                                                       result = (Node *) expr;
+                                                       result = (Node *) makeBoolExpr(NOT_EXPR,
+                                                                                                                  makeList1(rexpr));
                                                }
                                                break;
                                        case DISTINCT:
@@ -277,9 +270,12 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                        result = (Node *) make_op(a->name,
                                                                                                          lexpr,
                                                                                                          rexpr);
-                                                       if (((Expr *) result)->typeOid != BOOLOID)
+                                                       if (((OpExpr *) result)->opresulttype != BOOLOID)
                                                                elog(ERROR, "IS DISTINCT FROM requires = operator to yield boolean");
-                                                       ((Expr *) result)->opType = DISTINCT_EXPR;
+                                                       /*
+                                                        * We rely on DistinctExpr and OpExpr being same struct
+                                                        */
+                                                       NodeSetTag(result, T_DistinctExpr);
                                                }
                                                break;
                                        case OF:
@@ -433,7 +429,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                Node       *lexpr;
                                                Operator        optup;
                                                Form_pg_operator opform;
-                                               Oper       *newop;
+                                               OpExpr     *newop;
 
                                                right_list = lnext(right_list);
                                                if (tent->resdom->resjunk)
@@ -451,7 +447,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                 */
                                                optup = oper(op,
                                                                         exprType(lexpr),
-                                                                        exprType(tent->expr),
+                                                                        exprType((Node *) tent->expr),
                                                                         false);
                                                opform = (Form_pg_operator) GETSTRUCT(optup);
 
@@ -466,11 +462,15 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                                 " to be used with quantified predicate subquery",
                                                                 opname);
 
-                                               newop = makeOper(oprid(optup),  /* opno */
-                                                                                InvalidOid,    /* opid */
-                                                                                opform->oprresult,
-                                                                                false);
+                                               newop = makeNode(OpExpr);
+                                               newop->opno = oprid(optup);
+                                               newop->opfuncid = InvalidOid;
+                                               newop->opresulttype = opform->oprresult;
+                                               newop->opretset = false;
+                                               newop->args = NIL; /* for now */
+
                                                sublink->oper = lappend(sublink->oper, newop);
+
                                                ReleaseSysCache(optup);
                                        }
                                        if (left_list != NIL)
@@ -499,22 +499,24 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
 
                                        Assert(IsA(w, CaseWhen));
 
-                                       warg = w->expr;
+                                       warg = (Node *) w->expr;
                                        if (c->arg != NULL)
                                        {
                                                /* shorthand form was specified, so expand... */
                                                warg = (Node *) makeSimpleA_Expr(OP, "=",
-                                                                                                                c->arg, warg);
+                                                                                                                (Node *) c->arg,
+                                                                                                                warg);
                                        }
-                                       neww->expr = transformExpr(pstate, warg, domVal);
+                                       neww->expr = (Expr *) transformExpr(pstate, warg, domVal);
 
-                                       neww->expr = coerce_to_boolean(neww->expr, "CASE/WHEN");
+                                       neww->expr = (Expr *) coerce_to_boolean((Node *) neww->expr,
+                                                                                                                       "CASE/WHEN");
 
                                        /*
                                         * result is NULL for NULLIF() construct - thomas
                                         * 1998-11-11
                                         */
-                                       warg = w->result;
+                                       warg = (Node *) w->result;
                                        if (warg == NULL)
                                        {
                                                A_Const    *n = makeNode(A_Const);
@@ -522,10 +524,10 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                n->val.type = T_Null;
                                                warg = (Node *) n;
                                        }
-                                       neww->result = transformExpr(pstate, warg, domVal);
+                                       neww->result = (Expr *) transformExpr(pstate, warg, domVal);
 
                                        newargs = lappend(newargs, neww);
-                                       typeids = lappendi(typeids, exprType(neww->result));
+                                       typeids = lappendi(typeids, exprType((Node *) neww->result));
                                }
 
                                newc->args = newargs;
@@ -538,7 +540,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                newc->arg = NULL;
 
                                /* transform the default clause */
-                               defresult = c->defresult;
+                               defresult = (Node *) c->defresult;
                                if (defresult == NULL)
                                {
                                        A_Const    *n = makeNode(A_Const);
@@ -546,7 +548,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                        n->val.type = T_Null;
                                        defresult = (Node *) n;
                                }
-                               newc->defresult = transformExpr(pstate, defresult, domVal);
+                               newc->defresult = (Expr *) transformExpr(pstate, defresult, domVal);
 
                                /*
                                 * Note: default result is considered the most significant
@@ -554,24 +556,26 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                 * code worked before, but it seems a little bogus to me
                                 * --- tgl
                                 */
-                               typeids = lconsi(exprType(newc->defresult), typeids);
+                               typeids = lconsi(exprType((Node *) newc->defresult), typeids);
 
                                ptype = select_common_type(typeids, "CASE");
                                newc->casetype = ptype;
 
                                /* Convert default result clause, if necessary */
-                               newc->defresult = coerce_to_common_type(newc->defresult,
-                                                                                                               ptype,
-                                                                                                               "CASE/ELSE");
+                               newc->defresult = (Expr *)
+                                       coerce_to_common_type((Node *) newc->defresult,
+                                                                                 ptype,
+                                                                                 "CASE/ELSE");
 
                                /* Convert when-clause results, if necessary */
                                foreach(args, newc->args)
                                {
                                        CaseWhen   *w = (CaseWhen *) lfirst(args);
 
-                                       w->result = coerce_to_common_type(w->result,
-                                                                                                         ptype,
-                                                                                                         "CASE/WHEN");
+                                       w->result = (Expr *)
+                                               coerce_to_common_type((Node *) w->result,
+                                                                                         ptype,
+                                                                                         "CASE/WHEN");
                                }
 
                                result = (Node *) newc;
@@ -582,7 +586,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                        {
                                NullTest   *n = (NullTest *) expr;
 
-                               n->arg = transformExpr(pstate, n->arg, domVal);
+                               n->arg = (Expr *) transformExpr(pstate, (Node *) n->arg, domVal);
                                /* the argument can be any type, so don't coerce it */
                                result = expr;
                                break;
@@ -619,9 +623,9 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                                clausename = NULL;              /* keep compiler quiet */
                                }
 
-                               b->arg = transformExpr(pstate, b->arg, domVal);
+                               b->arg = (Expr *) transformExpr(pstate, (Node *) b->arg, domVal);
 
-                               b->arg = coerce_to_boolean(b->arg, clausename);
+                               b->arg = (Expr *) coerce_to_boolean((Node *) b->arg, clausename);
 
                                result = expr;
                                break;
@@ -885,36 +889,39 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 Oid
 exprType(Node *expr)
 {
-       Oid                     type = (Oid) InvalidOid;
+       Oid                     type;
 
        if (!expr)
-               return type;
+               return InvalidOid;
 
        switch (nodeTag(expr))
        {
                case T_Var:
                        type = ((Var *) expr)->vartype;
                        break;
-               case T_Expr:
-                       type = ((Expr *) expr)->typeOid;
-                       break;
                case T_Const:
                        type = ((Const *) expr)->consttype;
                        break;
-               case T_ArrayRef:
-                       type = ((ArrayRef *) expr)->refrestype;
+               case T_Param:
+                       type = ((Param *) expr)->paramtype;
                        break;
                case T_Aggref:
                        type = ((Aggref *) expr)->aggtype;
                        break;
-               case T_Param:
-                       type = ((Param *) expr)->paramtype;
+               case T_ArrayRef:
+                       type = ((ArrayRef *) expr)->refrestype;
                        break;
-               case T_FieldSelect:
-                       type = ((FieldSelect *) expr)->resulttype;
+               case T_FuncExpr:
+                       type = ((FuncExpr *) expr)->funcresulttype;
                        break;
-               case T_RelabelType:
-                       type = ((RelabelType *) expr)->resulttype;
+               case T_OpExpr:
+                       type = ((OpExpr *) expr)->opresulttype;
+                       break;
+               case T_DistinctExpr:
+                       type = ((DistinctExpr *) expr)->opresulttype;
+                       break;
+               case T_BoolExpr:
+                       type = BOOLOID;
                        break;
                case T_SubLink:
                        {
@@ -938,11 +945,17 @@ exprType(Node *expr)
                                }
                        }
                        break;
+               case T_FieldSelect:
+                       type = ((FieldSelect *) expr)->resulttype;
+                       break;
+               case T_RelabelType:
+                       type = ((RelabelType *) expr)->resulttype;
+                       break;
                case T_CaseExpr:
                        type = ((CaseExpr *) expr)->casetype;
                        break;
                case T_CaseWhen:
-                       type = exprType(((CaseWhen *) expr)->result);
+                       type = exprType((Node *) ((CaseWhen *) expr)->result);
                        break;
                case T_NullTest:
                        type = BOOLOID;
@@ -951,7 +964,7 @@ exprType(Node *expr)
                        type = BOOLOID;
                        break;
                case T_ConstraintTest:
-                       type = exprType(((ConstraintTest *) expr)->arg);
+                       type = exprType((Node *) ((ConstraintTest *) expr)->arg);
                        break;
                case T_ConstraintTestValue:
                        type = ((ConstraintTestValue *) expr)->typeId;
@@ -959,6 +972,7 @@ exprType(Node *expr)
                default:
                        elog(ERROR, "exprType: Do not know how to get type for %d node",
                                 nodeTag(expr));
+                       type = InvalidOid;      /* keep compiler quiet */
                        break;
        }
        return type;
@@ -995,7 +1009,7 @@ exprTypmod(Node *expr)
                                }
                        }
                        break;
-               case T_Expr:
+               case T_FuncExpr:
                        {
                                int32           coercedTypmod;
 
@@ -1021,9 +1035,9 @@ exprTypmod(Node *expr)
 
                                if (!cexpr->defresult)
                                        return -1;
-                               if (exprType(cexpr->defresult) != casetype)
+                               if (exprType((Node *) cexpr->defresult) != casetype)
                                        return -1;
-                               typmod = exprTypmod(cexpr->defresult);
+                               typmod = exprTypmod((Node *) cexpr->defresult);
                                if (typmod < 0)
                                        return -1;      /* no point in trying harder */
                                foreach(arg, cexpr->args)
@@ -1031,16 +1045,16 @@ exprTypmod(Node *expr)
                                        CaseWhen   *w = (CaseWhen *) lfirst(arg);
 
                                        Assert(IsA(w, CaseWhen));
-                                       if (exprType(w->result) != casetype)
+                                       if (exprType((Node *) w->result) != casetype)
                                                return -1;
-                                       if (exprTypmod(w->result) != typmod)
+                                       if (exprTypmod((Node *) w->result) != typmod)
                                                return -1;
                                }
                                return typmod;
                        }
                        break;
                case T_ConstraintTest:
-                       return exprTypmod(((ConstraintTest *) expr)->arg);
+                       return exprTypmod((Node *) ((ConstraintTest *) expr)->arg);
 
                default:
                        break;
@@ -1059,7 +1073,7 @@ exprTypmod(Node *expr)
 bool
 exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
 {
-       Func       *func;
+       FuncExpr   *func;
        int                     nargs;
        Const      *second_arg;
 
@@ -1067,12 +1081,9 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
                *coercedTypmod = -1;    /* default result on failure */
 
        /* Is it a function-call at all? */
-       if (expr == NULL ||
-               !IsA(expr, Expr) ||
-               ((Expr *) expr)->opType != FUNC_EXPR)
+       if (expr == NULL || !IsA(expr, FuncExpr))
                return false;
-       func = (Func *) (((Expr *) expr)->oper);
-       Assert(IsA(func, Func));
+       func = (FuncExpr *) expr;
 
        /*
         * If it didn't come from a coercion context, reject.
@@ -1086,11 +1097,11 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
         * argument being an int4 constant, it can't have been created from a
         * length coercion (it must be a type coercion, instead).
         */
-       nargs = length(((Expr *) expr)->args);
+       nargs = length(func->args);
        if (nargs < 2 || nargs > 3)
                return false;
 
-       second_arg = (Const *) lsecond(((Expr *) expr)->args);
+       second_arg = (Const *) lsecond(func->args);
        if (!IsA(second_arg, Const) ||
                second_arg->consttype != INT4OID ||
                second_arg->constisnull)
index 46d1bb0..4a2eb27 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.142 2002/11/13 00:39:47 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.143 2002/12/12 15:49:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -315,21 +315,15 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
        /* build the appropriate output structure */
        if (fdresult == FUNCDETAIL_NORMAL)
        {
-               Expr       *expr = makeNode(Expr);
-               Func       *funcnode = makeNode(Func);
+               FuncExpr   *funcexpr = makeNode(FuncExpr);
 
-               funcnode->funcid = funcid;
-               funcnode->funcresulttype = rettype;
-               funcnode->funcretset = retset;
-               funcnode->funcformat = COERCE_EXPLICIT_CALL;
-               funcnode->func_fcache = NULL;
+               funcexpr->funcid = funcid;
+               funcexpr->funcresulttype = rettype;
+               funcexpr->funcretset = retset;
+               funcexpr->funcformat = COERCE_EXPLICIT_CALL;
+               funcexpr->args = fargs;
 
-               expr->typeOid = rettype;
-               expr->opType = FUNC_EXPR;
-               expr->oper = (Node *) funcnode;
-               expr->args = fargs;
-
-               retval = (Node *) expr;
+               retval = (Node *) funcexpr;
        }
        else
        {
@@ -1182,7 +1176,7 @@ setup_field_select(Node *input, char *attname, Oid relid)
                elog(ERROR, "Relation \"%s\" has no column \"%s\"",
                         get_rel_name(relid), attname);
 
-       fselect->arg = input;
+       fselect->arg = (Expr *) input;
        fselect->fieldnum = attno;
        fselect->resulttype = get_atttype(relid, attno);
        fselect->resulttypmod = get_atttypmod(relid, attno);
index 088aaaf..a246344 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.74 2002/11/25 21:29:41 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.75 2002/12/12 15:49:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -89,10 +89,9 @@ make_op(List *opname, Node *ltree, Node *rtree)
                                rtypeId;
        Operator        tup;
        Form_pg_operator opform;
-       Oper       *newop;
        Node       *left,
                           *right;
-       Expr       *result;
+       OpExpr     *result;
 
        ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
        rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
@@ -124,15 +123,11 @@ make_op(List *opname, Node *ltree, Node *rtree)
                right = make_operand(rtree, rtypeId, opform->oprright);
        }
 
-       newop = makeOper(oprid(tup),    /* opno */
-                                        InvalidOid,    /* opid */
-                                        opform->oprresult, /* opresulttype */
-                                        get_func_retset(opform->oprcode)); /* opretset */
-
-       result = makeNode(Expr);
-       result->typeOid = opform->oprresult;
-       result->opType = OP_EXPR;
-       result->oper = (Node *) newop;
+       result = makeNode(OpExpr);
+       result->opno = oprid(tup);
+       result->opfuncid = InvalidOid;
+       result->opresulttype = opform->oprresult;
+       result->opretset = get_func_retset(opform->oprcode);
 
        if (!left)
                result->args = makeList1(right);
@@ -143,7 +138,7 @@ make_op(List *opname, Node *ltree, Node *rtree)
 
        ReleaseSysCache(tup);
 
-       return result;
+       return (Expr *) result;
 }      /* make_op() */
 
 
@@ -343,8 +338,8 @@ transformArraySubscripts(ParseState *pstate,
        aref->refelemalign = type_struct_element->typalign;
        aref->refupperindexpr = upperIndexpr;
        aref->reflowerindexpr = lowerIndexpr;
-       aref->refexpr = arrayBase;
-       aref->refassgnexpr = assignFrom;
+       aref->refexpr = (Expr *) arrayBase;
+       aref->refassgnexpr = (Expr *) assignFrom;
 
        ReleaseSysCache(type_tuple_array);
        ReleaseSysCache(type_tuple_element);
index 65c386a..4ae3bf2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.79 2002/09/04 20:31:24 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.80 2002/12/12 15:49:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1452,7 +1452,7 @@ expandRelAttrs(ParseState *pstate, RangeTblEntry *rte)
                                                                exprTypmod(varnode),
                                                                label,
                                                                false);
-               te->expr = varnode;
+               te->expr = (Expr *) varnode;
                te_list = lappend(te_list, te);
 
                names = lnext(names);
index 1a2da6d..5e4e23d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.92 2002/11/15 02:50:09 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.93 2002/12/12 15:49:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,7 +79,7 @@ transformTargetEntry(ParseState *pstate,
                                                 colname,
                                                 resjunk);
 
-       return makeTargetEntry(resnode, expr);
+       return makeTargetEntry(resnode, (Expr *) expr);
 }
 
 
@@ -225,7 +225,7 @@ updateTargetListEntry(ParseState *pstate,
                                          int attrno,
                                          List *indirection)
 {
-       Oid                     type_id = exprType(tle->expr);  /* type of value provided */
+       Oid                     type_id = exprType((Node *) tle->expr); /* type of value provided */
        Oid                     attrtype;               /* type of target column */
        int32           attrtypmod;
        Resdom     *resnode = tle->resdom;
@@ -277,8 +277,8 @@ updateTargetListEntry(ParseState *pstate,
                                                                                attrtypmod,
                                                                                indirection,
                                                                                pstate->p_is_insert,
-                                                                               tle->expr);
-               tle->expr = (Node *) aref;
+                                                                               (Node *) tle->expr);
+               tle->expr = (Expr *) aref;
        }
        else
        {
@@ -289,10 +289,11 @@ updateTargetListEntry(ParseState *pstate,
                 */
                if (type_id != InvalidOid)
                {
-                       tle->expr = coerce_to_target_type(tle->expr, type_id,
-                                                                                         attrtype, attrtypmod,
-                                                                                         COERCION_ASSIGNMENT,
-                                                                                         COERCE_IMPLICIT_CAST);
+                       tle->expr = (Expr *)
+                               coerce_to_target_type((Node *) tle->expr, type_id,
+                                                                         attrtype, attrtypmod,
+                                                                         COERCION_ASSIGNMENT,
+                                                                         COERCE_IMPLICIT_CAST);
                        if (tle->expr == NULL)
                                elog(ERROR, "column \"%s\" is of type %s"
                                         " but expression is of type %s"
@@ -501,7 +502,7 @@ FigureColnameInternal(Node *node, char **name)
                        }
                        break;
                case T_CaseExpr:
-                       strength = FigureColnameInternal(((CaseExpr *) node)->defresult,
+                       strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
                                                                                         name);
                        if (strength <= 1)
                        {
index bb58db8..d0badcc 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.113 2002/10/20 00:58:55 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.114 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -304,7 +304,7 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
                                                                                                         att_tup->atttypmod,
                                                                          pstrdup(NameStr(att_tup->attname)),
                                                                                                         false),
-                                                                                 new_expr);
+                                                                                 (Expr *) new_expr);
                }
 
                if (new_tle)
@@ -389,10 +389,10 @@ process_matched_tle(TargetEntry *src_tle,
         * Prior TLE could be a nest of ArrayRefs if we do this more than
         * once.
         */
-       priorbottom = ((ArrayRef *) prior_tle->expr)->refexpr;
+       priorbottom = (Node *) ((ArrayRef *) prior_tle->expr)->refexpr;
        while (priorbottom != NULL && IsA(priorbottom, ArrayRef) &&
                   ((ArrayRef *) priorbottom)->refassgnexpr != NULL)
-               priorbottom = ((ArrayRef *) priorbottom)->refexpr;
+               priorbottom = (Node *) ((ArrayRef *) priorbottom)->refexpr;
        if (!equal(priorbottom, ((ArrayRef *) src_tle->expr)->refexpr))
                elog(ERROR, "Multiple assignments to same attribute \"%s\"",
                         resdom->resname);
@@ -404,7 +404,7 @@ process_matched_tle(TargetEntry *src_tle,
        memcpy(newexpr, src_tle->expr, sizeof(ArrayRef));
        newexpr->refexpr = prior_tle->expr;
 
-       return makeTargetEntry(resdom, (Node *) newexpr);
+       return makeTargetEntry(resdom, (Expr *) newexpr);
 }
 
 
index 94a9406..22e7eee 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.67 2002/10/20 00:58:55 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.68 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -706,7 +706,7 @@ AddInvertedQual(Query *parsetree, Node *qual)
 
        /* Need not copy input qual, because AddQual will... */
        invqual = makeNode(BooleanTest);
-       invqual->arg = qual;
+       invqual->arg = (Expr *) qual;
        invqual->booltesttype = IS_NOT_TRUE;
 
        AddQual(parsetree, (Node *) invqual);
@@ -724,7 +724,7 @@ FindMatchingNew(List *tlist, int attno)
                TargetEntry *tle = lfirst(i);
 
                if (tle->resdom->resno == attno)
-                       return tle->expr;
+                       return (Node *) tle->expr;
        }
        return NULL;
 }
index b8189e8..104f93a 100644 (file)
@@ -17,7 +17,7 @@
  *
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.45 2002/12/05 04:04:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.46 2002/12/12 15:49:40 tgl Exp $
  *
  * ----------
  */
@@ -35,6 +35,7 @@
 #include "catalog/pg_operator.h"
 #include "commands/trigger.h"
 #include "executor/spi_priv.h"
+#include "optimizer/planmain.h"
 #include "parser/parse_oper.h"
 #include "utils/lsyscache.h"
 #include "miscadmin.h"
@@ -2747,6 +2748,7 @@ RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
                                                                nth(defval[j].adnum - 1,
                                                                        spi_plan->targetlist);
                                                        spi_qptle->expr = stringToNode(defval[j].adbin);
+                                                       fix_opfuncids((Node *) spi_qptle->expr);
 
                                                        break;
                                                }
@@ -3037,6 +3039,7 @@ RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
                                                                        nth(defval[j].adnum - 1,
                                                                                spi_plan->targetlist);
                                                                spi_qptle->expr = stringToNode(defval[j].adbin);
+                                                               fix_opfuncids((Node *) spi_qptle->expr);
 
                                                                break;
                                                        }
index c5a0f0d..92f69a3 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.127 2002/11/26 03:01:58 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.128 2002/12/12 15:49:40 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -149,13 +149,13 @@ static RangeTblEntry *find_rte_by_refname(const char *refname,
                                        deparse_context *context);
 static void get_rule_expr(Node *node, deparse_context *context,
                                                  bool showimplicit);
-static void get_oper_expr(Expr *expr, deparse_context *context);
-static void get_func_expr(Expr *expr, deparse_context *context,
+static void get_oper_expr(OpExpr *expr, deparse_context *context);
+static void get_func_expr(FuncExpr *expr, deparse_context *context,
                                                  bool showimplicit);
 static void get_agg_expr(Aggref *aggref, deparse_context *context);
 static Node *strip_type_coercion(Node *expr, Oid resultType);
 static void get_const_expr(Const *constval, deparse_context *context);
-static void get_sublink_expr(Node *node, deparse_context *context);
+static void get_sublink_expr(SubLink *sublink, deparse_context *context);
 static void get_from_clause(Query *query, deparse_context *context);
 static void get_from_clause_item(Node *jtnode, Query *query,
                                         deparse_context *context);
@@ -1434,7 +1434,7 @@ get_basic_select_query(Query *query, deparse_context *context,
                sep = ", ";
                colno++;
 
-               get_rule_expr(tle->expr, context, true);
+               get_rule_expr((Node *) tle->expr, context, true);
 
                /*
                 * Figure out what the result column should be called.  In the
@@ -1565,7 +1565,7 @@ get_rule_sortgroupclause(SortClause *srt, List *tlist, bool force_colno,
        Node       *expr;
 
        tle = get_sortgroupclause_tle(srt, tlist);
-       expr = tle->expr;
+       expr = (Node *) tle->expr;
 
        /*
         * Use column-number form if requested by caller or if expression is a
@@ -1647,7 +1647,7 @@ get_insert_query_def(Query *query, deparse_context *context)
 
                        appendStringInfo(buf, sep);
                        sep = ", ";
-                       get_rule_expr(tle->expr, context, false);
+                       get_rule_expr((Node *) tle->expr, context, false);
                }
                appendStringInfoChar(buf, ')');
        }
@@ -1697,7 +1697,7 @@ get_update_query_def(Query *query, deparse_context *context)
                if (!tleIsArrayAssign(tle))
                        appendStringInfo(buf, "%s = ",
                                                         quote_identifier(tle->resdom->resname));
-               get_rule_expr(tle->expr, context, false);
+               get_rule_expr((Node *) tle->expr, context, false);
        }
 
        /* Add the FROM clause if needed */
@@ -1924,10 +1924,6 @@ get_rule_expr(Node *node, deparse_context *context,
         */
        switch (nodeTag(node))
        {
-               case T_Const:
-                       get_const_expr((Const *) node, context);
-                       break;
-
                case T_Var:
                        {
                                Var                *var = (Var *) node;
@@ -1958,82 +1954,26 @@ get_rule_expr(Node *node, deparse_context *context,
                        }
                        break;
 
-               case T_Expr:
+               case T_Const:
+                       get_const_expr((Const *) node, context);
+                       break;
+
+               case T_Param:
                        {
-                               Expr       *expr = (Expr *) node;
-                               List       *args = expr->args;
+                               Param      *param = (Param *) node;
 
-                               /*
-                                * Expr nodes have to be handled a bit detailed
-                                */
-                               switch (expr->opType)
+                               switch (param->paramkind)
                                {
-                                       case OP_EXPR:
-                                               get_oper_expr(expr, context);
-                                               break;
-
-                                       case DISTINCT_EXPR:
-                                               appendStringInfoChar(buf, '(');
-                                               Assert(length(args) == 2);
-                                               {
-                                                       /* binary operator */
-                                                       Node       *arg1 = (Node *) lfirst(args);
-                                                       Node       *arg2 = (Node *) lsecond(args);
-
-                                                       get_rule_expr(arg1, context, true);
-                                                       appendStringInfo(buf, " IS DISTINCT FROM ");
-                                                       get_rule_expr(arg2, context, true);
-                                               }
-                                               appendStringInfoChar(buf, ')');
-                                               break;
-
-                                       case FUNC_EXPR:
-                                               get_func_expr(expr, context, showimplicit);
-                                               break;
-
-                                       case OR_EXPR:
-                                               appendStringInfoChar(buf, '(');
-                                               get_rule_expr((Node *) lfirst(args), context, false);
-                                               while ((args = lnext(args)) != NIL)
-                                               {
-                                                       appendStringInfo(buf, " OR ");
-                                                       get_rule_expr((Node *) lfirst(args), context,
-                                                                                 false);
-                                               }
-                                               appendStringInfoChar(buf, ')');
-                                               break;
-
-                                       case AND_EXPR:
-                                               appendStringInfoChar(buf, '(');
-                                               get_rule_expr((Node *) lfirst(args), context, false);
-                                               while ((args = lnext(args)) != NIL)
-                                               {
-                                                       appendStringInfo(buf, " AND ");
-                                                       get_rule_expr((Node *) lfirst(args), context,
-                                                                                 false);
-                                               }
-                                               appendStringInfoChar(buf, ')');
-                                               break;
-
-                                       case NOT_EXPR:
-                                               appendStringInfo(buf, "(NOT ");
-                                               get_rule_expr((Node *) lfirst(args), context, false);
-                                               appendStringInfoChar(buf, ')');
+                                       case PARAM_NAMED:
+                                               appendStringInfo(buf, "$%s", param->paramname);
                                                break;
-
-                                       case SUBPLAN_EXPR:
-
-                                               /*
-                                                * We cannot see an already-planned subplan in
-                                                * rule deparsing, only while EXPLAINing a query
-                                                * plan. For now, just punt.
-                                                */
-                                               appendStringInfo(buf, "(subplan)");
+                                       case PARAM_NUM:
+                                       case PARAM_EXEC:
+                                               appendStringInfo(buf, "$%d", param->paramid);
                                                break;
-
                                        default:
-                                               elog(ERROR, "get_rule_expr: expr opType %d not supported",
-                                                        expr->opType);
+                                               appendStringInfo(buf, "(param)");
+                                               break;
                                }
                        }
                        break;
@@ -2058,7 +1998,7 @@ get_rule_expr(Node *node, deparse_context *context,
                                 */
                                if (aref->refassgnexpr)
                                        context->varprefix = false;
-                               get_rule_expr(aref->refexpr, context, showimplicit);
+                               get_rule_expr((Node *) aref->refexpr, context, showimplicit);
                                context->varprefix = savevarprefix;
                                lowlist = aref->reflowerindexpr;
                                foreach(uplist, aref->refupperindexpr)
@@ -2077,15 +2017,103 @@ get_rule_expr(Node *node, deparse_context *context,
                                if (aref->refassgnexpr)
                                {
                                        appendStringInfo(buf, " = ");
-                                       get_rule_expr(aref->refassgnexpr, context, showimplicit);
+                                       get_rule_expr((Node *) aref->refassgnexpr, context,
+                                                                 showimplicit);
+                               }
+                       }
+                       break;
+
+               case T_FuncExpr:
+                       get_func_expr((FuncExpr *) node, context, showimplicit);
+                       break;
+
+               case T_OpExpr:
+                       get_oper_expr((OpExpr *) node, context);
+                       break;
+
+               case T_DistinctExpr:
+                       {
+                               DistinctExpr *expr = (DistinctExpr *) node;
+                               List       *args = expr->args;
+
+                               Assert(length(args) == 2);
+                               {
+                                       /* binary operator */
+                                       Node       *arg1 = (Node *) lfirst(args);
+                                       Node       *arg2 = (Node *) lsecond(args);
+
+                                       appendStringInfoChar(buf, '(');
+                                       get_rule_expr(arg1, context, true);
+                                       appendStringInfo(buf, " IS DISTINCT FROM ");
+                                       get_rule_expr(arg2, context, true);
+                                       appendStringInfoChar(buf, ')');
                                }
                        }
                        break;
 
+               case T_BoolExpr:
+                       {
+                               BoolExpr   *expr = (BoolExpr *) node;
+                               List       *args = expr->args;
+
+                               switch (expr->boolop)
+                               {
+                                       case AND_EXPR:
+                                               appendStringInfoChar(buf, '(');
+                                               get_rule_expr((Node *) lfirst(args), context, false);
+                                               while ((args = lnext(args)) != NIL)
+                                               {
+                                                       appendStringInfo(buf, " AND ");
+                                                       get_rule_expr((Node *) lfirst(args), context,
+                                                                                 false);
+                                               }
+                                               appendStringInfoChar(buf, ')');
+                                               break;
+
+                                       case OR_EXPR:
+                                               appendStringInfoChar(buf, '(');
+                                               get_rule_expr((Node *) lfirst(args), context, false);
+                                               while ((args = lnext(args)) != NIL)
+                                               {
+                                                       appendStringInfo(buf, " OR ");
+                                                       get_rule_expr((Node *) lfirst(args), context,
+                                                                                 false);
+                                               }
+                                               appendStringInfoChar(buf, ')');
+                                               break;
+
+                                       case NOT_EXPR:
+                                               appendStringInfo(buf, "(NOT ");
+                                               get_rule_expr((Node *) lfirst(args), context, false);
+                                               appendStringInfoChar(buf, ')');
+                                               break;
+
+                                       default:
+                                               elog(ERROR, "get_rule_expr: unknown boolop %d",
+                                                        (int) expr->boolop);
+                               }
+                       }
+                       break;
+
+               case T_SubLink:
+                       get_sublink_expr((SubLink *) node, context);
+                       break;
+
+               case T_SubPlanExpr:
+                       {
+                               /*
+                                * We cannot see an already-planned subplan in
+                                * rule deparsing, only while EXPLAINing a query
+                                * plan. For now, just punt.
+                                */
+                               appendStringInfo(buf, "(subplan)");
+                       }
+                       break;
+
                case T_FieldSelect:
                        {
                                FieldSelect *fselect = (FieldSelect *) node;
-                               Oid                     argType = exprType(fselect->arg);
+                               Oid                     argType = exprType((Node *) fselect->arg);
                                Oid                     typrelid;
                                char       *fieldname;
 
@@ -2103,7 +2131,7 @@ get_rule_expr(Node *node, deparse_context *context,
                                 * are *not* simple.  So, always use parenthesized syntax.
                                 */
                                appendStringInfoChar(buf, '(');
-                               get_rule_expr(fselect->arg, context, true);
+                               get_rule_expr((Node *) fselect->arg, context, true);
                                appendStringInfo(buf, ").%s", quote_identifier(fieldname));
                        }
                        break;
@@ -2111,7 +2139,7 @@ get_rule_expr(Node *node, deparse_context *context,
                case T_RelabelType:
                        {
                                RelabelType *relabel = (RelabelType *) node;
-                               Node   *arg = relabel->arg;
+                               Node   *arg = (Node *) relabel->arg;
 
                                if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
                                        !showimplicit)
@@ -2149,12 +2177,12 @@ get_rule_expr(Node *node, deparse_context *context,
                                        CaseWhen   *when = (CaseWhen *) lfirst(temp);
 
                                        appendStringInfo(buf, " WHEN ");
-                                       get_rule_expr(when->expr, context, false);
+                                       get_rule_expr((Node *) when->expr, context, false);
                                        appendStringInfo(buf, " THEN ");
-                                       get_rule_expr(when->result, context, true);
+                                       get_rule_expr((Node *) when->result, context, true);
                                }
                                appendStringInfo(buf, " ELSE ");
-                               get_rule_expr(caseexpr->defresult, context, true);
+                               get_rule_expr((Node *) caseexpr->defresult, context, true);
                                appendStringInfo(buf, " END");
                        }
                        break;
@@ -2164,7 +2192,7 @@ get_rule_expr(Node *node, deparse_context *context,
                                NullTest   *ntest = (NullTest *) node;
 
                                appendStringInfo(buf, "(");
-                               get_rule_expr(ntest->arg, context, true);
+                               get_rule_expr((Node *) ntest->arg, context, true);
                                switch (ntest->nulltesttype)
                                {
                                        case IS_NULL:
@@ -2185,7 +2213,7 @@ get_rule_expr(Node *node, deparse_context *context,
                                BooleanTest *btest = (BooleanTest *) node;
 
                                appendStringInfo(buf, "(");
-                               get_rule_expr(btest->arg, context, false);
+                               get_rule_expr((Node *) btest->arg, context, false);
                                switch (btest->booltesttype)
                                {
                                        case IS_TRUE:
@@ -2221,38 +2249,12 @@ get_rule_expr(Node *node, deparse_context *context,
                                 * We assume that the operations of the constraint node
                                 * need not be explicitly represented in the output.
                                 */
-                               get_rule_expr(ctest->arg, context, showimplicit);
+                               get_rule_expr((Node *) ctest->arg, context, showimplicit);
                        }
                        break;
 
                case T_ConstraintTestValue:
-                       {
-                               appendStringInfo(buf, "VALUE");
-                       }
-                       break;
-
-               case T_SubLink:
-                       get_sublink_expr(node, context);
-                       break;
-
-               case T_Param:
-                       {
-                               Param      *param = (Param *) node;
-
-                               switch (param->paramkind)
-                               {
-                                       case PARAM_NAMED:
-                                               appendStringInfo(buf, "$%s", param->paramname);
-                                               break;
-                                       case PARAM_NUM:
-                                       case PARAM_EXEC:
-                                               appendStringInfo(buf, "$%d", param->paramid);
-                                               break;
-                                       default:
-                                               appendStringInfo(buf, "(param)");
-                                               break;
-                               }
-                       }
+                       appendStringInfo(buf, "VALUE");
                        break;
 
                default:
@@ -2263,13 +2265,13 @@ get_rule_expr(Node *node, deparse_context *context,
 
 
 /*
- * get_oper_expr                       - Parse back an Oper node
+ * get_oper_expr                       - Parse back an OpExpr node
  */
 static void
-get_oper_expr(Expr *expr, deparse_context *context)
+get_oper_expr(OpExpr *expr, deparse_context *context)
 {
        StringInfo      buf = context->buf;
-       Oid                     opno = ((Oper *) expr->oper)->opno;
+       Oid                     opno = expr->opno;
        List       *args = expr->args;
 
        appendStringInfoChar(buf, '(');
@@ -2324,15 +2326,14 @@ get_oper_expr(Expr *expr, deparse_context *context)
 }
 
 /*
- * get_func_expr                       - Parse back a Func node
+ * get_func_expr                       - Parse back a FuncExpr node
  */
 static void
-get_func_expr(Expr *expr, deparse_context *context,
+get_func_expr(FuncExpr *expr, deparse_context *context,
                          bool showimplicit)
 {
        StringInfo      buf = context->buf;
-       Func       *func = (Func *) (expr->oper);
-       Oid                     funcoid = func->funcid;
+       Oid                     funcoid = expr->funcid;
        Oid                     argtypes[FUNC_MAX_ARGS];
        int                     nargs;
        List       *l;
@@ -2342,7 +2343,7 @@ get_func_expr(Expr *expr, deparse_context *context,
         * If the function call came from an implicit coercion, then just show
         * the first argument --- unless caller wants to see implicit coercions.
         */
-       if (func->funcformat == COERCE_IMPLICIT_CAST && !showimplicit)
+       if (expr->funcformat == COERCE_IMPLICIT_CAST && !showimplicit)
        {
                get_rule_expr((Node *) lfirst(expr->args), context, showimplicit);
                return;
@@ -2352,11 +2353,11 @@ get_func_expr(Expr *expr, deparse_context *context,
         * If the function call came from a cast, then show
         * the first argument plus an explicit cast operation.
         */
-       if (func->funcformat == COERCE_EXPLICIT_CAST ||
-               func->funcformat == COERCE_IMPLICIT_CAST)
+       if (expr->funcformat == COERCE_EXPLICIT_CAST ||
+               expr->funcformat == COERCE_IMPLICIT_CAST)
        {
                Node       *arg = lfirst(expr->args);
-               Oid                     rettype = expr->typeOid;
+               Oid                     rettype = expr->funcresulttype;
                int32           coercedTypmod;
 
                /* Get the typmod if this is a length-coercion function */
@@ -2410,7 +2411,7 @@ static void
 get_agg_expr(Aggref *aggref, deparse_context *context)
 {
        StringInfo      buf = context->buf;
-       Oid                     argtype = exprType(aggref->target);
+       Oid                     argtype = exprType((Node *) aggref->target);
 
        appendStringInfo(buf, "%s(%s",
                                   generate_function_name(aggref->aggfnoid, 1, &argtype),
@@ -2418,7 +2419,7 @@ get_agg_expr(Aggref *aggref, deparse_context *context)
        if (aggref->aggstar)
                appendStringInfo(buf, "*");
        else
-               get_rule_expr(aggref->target, context, true);
+               get_rule_expr((Node *) aggref->target, context, true);
        appendStringInfoChar(buf, ')');
 }
 
@@ -2442,14 +2443,12 @@ strip_type_coercion(Node *expr, Oid resultType)
 
        if (IsA(expr, RelabelType) &&
                ((RelabelType *) expr)->resulttypmod == -1)
-               return ((RelabelType *) expr)->arg;
+               return (Node *) ((RelabelType *) expr)->arg;
 
-       if (IsA(expr, Expr) &&
-               ((Expr *) expr)->opType == FUNC_EXPR)
+       if (IsA(expr, FuncExpr))
        {
-               Func       *func = (Func *) (((Expr *) expr)->oper);
+               FuncExpr   *func = (FuncExpr *) expr;
 
-               Assert(IsA(func, Func));
                if (func->funcformat != COERCE_EXPLICIT_CAST &&
                        func->funcformat != COERCE_IMPLICIT_CAST)
                        return expr;            /* don't absorb into upper coercion */
@@ -2457,7 +2456,7 @@ strip_type_coercion(Node *expr, Oid resultType)
                if (exprIsLengthCoercion(expr, NULL))
                        return expr;
 
-               return (Node *) lfirst(((Expr *) expr)->args);
+               return (Node *) lfirst(func->args);
        }
 
        return expr;
@@ -2609,14 +2608,13 @@ get_const_expr(Const *constval, deparse_context *context)
  * ----------
  */
 static void
-get_sublink_expr(Node *node, deparse_context *context)
+get_sublink_expr(SubLink *sublink, deparse_context *context)
 {
        StringInfo      buf = context->buf;
-       SubLink    *sublink = (SubLink *) node;
        Query      *query = (Query *) (sublink->subselect);
        List       *l;
        char       *sep;
-       Oper       *oper;
+       OpExpr     *oper;
        bool            need_paren;
 
        appendStringInfoChar(buf, '(');
@@ -2657,17 +2655,17 @@ get_sublink_expr(Node *node, deparse_context *context)
                        break;
 
                case ANY_SUBLINK:
-                       oper = (Oper *) lfirst(sublink->oper);
+                       oper = (OpExpr *) lfirst(sublink->oper);
                        appendStringInfo(buf, "%s ANY ", get_opname(oper->opno));
                        break;
 
                case ALL_SUBLINK:
-                       oper = (Oper *) lfirst(sublink->oper);
+                       oper = (OpExpr *) lfirst(sublink->oper);
                        appendStringInfo(buf, "%s ALL ", get_opname(oper->opno));
                        break;
 
                case MULTIEXPR_SUBLINK:
-                       oper = (Oper *) lfirst(sublink->oper);
+                       oper = (OpExpr *) lfirst(sublink->oper);
                        appendStringInfo(buf, "%s ", get_opname(oper->opno));
                        break;
 
index 827b000..c378f8b 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.122 2002/11/25 21:29:42 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.123 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1025,7 +1025,7 @@ booltestsel(Query *root, BoolTestType booltesttype, Node *arg, int varRelid)
         * can't hurt)
         */
        if (IsA(arg, RelabelType))
-               arg = ((RelabelType *) arg)->arg;
+               arg = (Node *) ((RelabelType *) arg)->arg;
 
        if (IsA(arg, Var) &&(varRelid == 0 || varRelid == ((Var *) arg)->varno))
                var = (Var *) arg;
@@ -1246,7 +1246,7 @@ nulltestsel(Query *root, NullTestType nulltesttype, Node *arg, int varRelid)
         * Ignore any binary-compatible relabeling
         */
        if (IsA(arg, RelabelType))
-               arg = ((RelabelType *) arg)->arg;
+               arg = (Node *) ((RelabelType *) arg)->arg;
 
        if (IsA(arg, Var) &&
                (varRelid == 0 || varRelid == ((Var *) arg)->varno))
@@ -1753,14 +1753,15 @@ mergejoinscansel(Query *root, Node *clause,
        /* Deconstruct the merge clause */
        if (!is_opclause(clause))
                return;                                 /* shouldn't happen */
-       opno = ((Oper *) ((Expr *) clause)->oper)->opno;
+       opno = ((OpExpr *) clause)->opno;
        left = get_leftop((Expr *) clause);
        right = get_rightop((Expr *) clause);
        if (!right)
                return;                                 /* shouldn't happen */
 
        /* Can't do anything if inputs are not Vars */
-       if (!IsA(left, Var) ||!IsA(right, Var))
+       if (!IsA(left, Var) ||
+               !IsA(right, Var))
                return;
 
        /* Verify mergejoinability and get left and right "<" operators */
@@ -2842,9 +2843,9 @@ get_restriction_var(List *args,
        /* Ignore any binary-compatible relabeling */
 
        if (IsA(left, RelabelType))
-               left = ((RelabelType *) left)->arg;
+               left = (Node *) ((RelabelType *) left)->arg;
        if (IsA(right, RelabelType))
-               right = ((RelabelType *) right)->arg;
+               right = (Node *) ((RelabelType *) right)->arg;
 
        /* Look for the var */
 
@@ -2895,9 +2896,9 @@ get_join_vars(List *args, Var **var1, Var **var2)
 
        /* Ignore any binary-compatible relabeling */
        if (IsA(left, RelabelType))
-               left = ((RelabelType *) left)->arg;
+               left = (Node *) ((RelabelType *) left)->arg;
        if (IsA(right, RelabelType))
-               right = ((RelabelType *) right)->arg;
+               right = (Node *) ((RelabelType *) right)->arg;
 
        if (IsA(left, Var))
                *var1 = (Var *) left;
index 8cb41a9..fa31318 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.168 2002/12/06 05:20:24 momjian Exp $
+ * $Id: catversion.h,v 1.169 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200212061
+#define CATALOG_VERSION_NO     200212101
 
 #endif
index c573cf9..e025c9d 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodeSubplan.h,v 1.12 2002/12/05 15:50:38 tgl Exp $
+ * $Id: nodeSubplan.h,v 1.13 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,7 +16,7 @@
 
 #include "nodes/execnodes.h"
 
-extern SubPlanState *ExecInitSubPlan(SubPlan *node, EState *estate);
+extern SubPlanState *ExecInitSubPlan(SubPlanExpr *node, EState *estate);
 extern Datum ExecSubPlan(SubPlanState *node, List *pvar, ExprContext *econtext,
                        bool *isNull);
 extern void ExecEndSubPlan(SubPlanState *node);
index 68f0dcd..d1f4ebf 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: makefuncs.h,v 1.42 2002/11/25 21:29:42 tgl Exp $
+ * $Id: makefuncs.h,v 1.43 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,18 +22,13 @@ extern A_Expr *makeA_Expr(int oper, List *name, Node *lexpr, Node *rexpr);
 extern A_Expr *makeSimpleA_Expr(int oper, const char *name,
                                 Node *lexpr, Node *rexpr);
 
-extern Oper *makeOper(Oid opno,
-                Oid opid,
-                Oid opresulttype,
-                bool opretset);
-
 extern Var *makeVar(Index varno,
                AttrNumber varattno,
                Oid vartype,
                int32 vartypmod,
                Index varlevelsup);
 
-extern TargetEntry *makeTargetEntry(Resdom *resdom, Node *expr);
+extern TargetEntry *makeTargetEntry(Resdom *resdom, Expr *expr);
 
 extern Resdom *makeResdom(AttrNumber resno,
                   Oid restype,
@@ -49,9 +44,11 @@ extern Const *makeConst(Oid consttype,
 
 extern Const *makeNullConst(Oid consttype);
 
+extern Expr *makeBoolExpr(BoolExprType boolop, List *args);
+
 extern Alias *makeAlias(const char *aliasname, List *colnames);
 
-extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod,
+extern RelabelType *makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod,
                                                                        CoercionForm rformat);
 
 extern RangeVar *makeRangeVar(char *schemaname, char *relname);
index 7db0525..99e1a62 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodeFuncs.h,v 1.17 2002/06/20 20:29:51 momjian Exp $
+ * $Id: nodeFuncs.h,v 1.18 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,6 @@
 extern bool single_node(Node *node);
 extern bool var_is_outer(Var *var);
 extern bool var_is_rel(Var *var);
-extern Oper *replace_opid(Oper *oper);
+extern void set_opfuncid(OpExpr *opexpr);
 
 #endif   /* NODEFUNCS_H */
index 2f3e714..aacdf60 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.129 2002/12/06 05:00:31 momjian Exp $
+ * $Id: nodes.h,v 1.130 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -62,7 +62,6 @@ typedef enum NodeTag
        T_Hash,
        T_SetOp,
        T_Limit,
-       T_SubPlan,
 
        /*
         * TAGS FOR PLAN STATE NODES (execnodes.h)
@@ -96,21 +95,32 @@ typedef enum NodeTag
         * TAGS FOR PRIMITIVE NODES (primnodes.h)
         */
        T_Resdom = 300,
-       T_Fjoin,
+       T_Alias,
+       T_RangeVar,
        T_Expr,
        T_Var,
-       T_Oper,
        T_Const,
        T_Param,
        T_Aggref,
+       T_ArrayRef,
+       T_FuncExpr,
+       T_OpExpr,
+       T_DistinctExpr,
+       T_BoolExpr,
        T_SubLink,
-       T_Func,
+       T_SubPlanExpr,
        T_FieldSelect,
-       T_ArrayRef,
        T_RelabelType,
+       T_CaseExpr,
+       T_CaseWhen,
+       T_NullTest,
+       T_BooleanTest,
+       T_ConstraintTest,
+       T_ConstraintTestValue,
+       T_TargetEntry,
        T_RangeTblRef,
-       T_FromExpr,
        T_JoinExpr,
+       T_FromExpr,
 
        /*
         * TAGS FOR PLANNER NODES (relation.h)
@@ -183,7 +193,6 @@ typedef enum NodeTag
        T_ViewStmt,
        T_LoadStmt,
        T_CreateDomainStmt,
-       T_DomainConstraintValue,
        T_CreatedbStmt,
        T_DropdbStmt,
        T_VacuumStmt,
@@ -228,30 +237,22 @@ typedef enum NodeTag
        T_ResTarget,
        T_TypeCast,
        T_SortGroupBy,
-       T_Alias,
-       T_RangeVar,
        T_RangeSubselect,
        T_RangeFunction,
        T_TypeName,
-       T_IndexElem,
        T_ColumnDef,
+       T_IndexElem,
        T_Constraint,
        T_DefElem,
-       T_TargetEntry,
        T_RangeTblEntry,
        T_SortClause,
        T_GroupClause,
-       T_NullTest,
-       T_BooleanTest,
-       T_ConstraintTest,
-       T_ConstraintTestValue,
-       T_CaseExpr,
-       T_CaseWhen,
        T_FkConstraint,
        T_PrivGrantee,
        T_FuncWithArgs,
        T_PrivTarget,
        T_InsertDefault,
+       T_DomainConstraintValue,
        T_CreateOpClassItem,
        T_CompositeTypeStmt,
 
index 5201e1b..f2d9243 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.221 2002/12/06 05:00:32 momjian Exp $
+ * $Id: parsenodes.h,v 1.222 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,7 @@ typedef enum QuerySource
 
 /*
  * Query -
- *       all statments are turned into a Query tree (via transformStmt)
+ *       all statements are turned into a Query tree (via transformStmt)
  *       for further processing by the optimizer
  *       utility statements (i.e. non-optimizable statements)
  *       have the *utilityStmt field set.
@@ -202,145 +202,6 @@ typedef struct TypeCast
 } TypeCast;
 
 /*
- * CaseExpr - a CASE expression
- */
-typedef struct CaseExpr
-{
-       NodeTag         type;
-       Oid                     casetype;
-       Node       *arg;                        /* implicit equality comparison argument */
-       List       *args;                       /* the arguments (list of WHEN clauses) */
-       Node       *defresult;          /* the default result (ELSE clause) */
-} CaseExpr;
-
-/*
- * CaseWhen - an argument to a CASE expression
- */
-typedef struct CaseWhen
-{
-       NodeTag         type;
-       Node       *expr;                       /* comparison expression */
-       Node       *result;                     /* substitution result */
-} CaseWhen;
-
-/* ----------------
- * NullTest
- *
- * NullTest represents the operation of testing a value for NULLness.
- * Currently, we only support scalar input values, but eventually a
- * row-constructor input should be supported.
- * The appropriate test is performed and returned as a boolean Datum.
- * ----------------
- */
-
-typedef enum NullTestType
-{
-       IS_NULL, IS_NOT_NULL
-} NullTestType;
-
-typedef struct NullTest
-{
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
-       NullTestType nulltesttype;      /* IS NULL, IS NOT NULL */
-} NullTest;
-
-/*
- * BooleanTest
- *
- * BooleanTest represents the operation of determining whether a boolean
- * is TRUE, FALSE, or UNKNOWN (ie, NULL).  All six meaningful combinations
- * are supported.  Note that a NULL input does *not* cause a NULL result.
- * The appropriate test is performed and returned as a boolean Datum.
- */
-
-typedef enum BoolTestType
-{
-       IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN
-} BoolTestType;
-
-typedef struct BooleanTest
-{
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
-       BoolTestType booltesttype;      /* test type */
-} BooleanTest;
-
-/*
- * ConstraintTest
- *
- * ConstraintTest represents the operation of testing a value to see whether
- * it meets a constraint.  If so, the input value is returned as the result;
- * if not, an error is raised.
- */
-
-typedef enum ConstraintTestType
-{
-       CONSTR_TEST_NOTNULL,
-       CONSTR_TEST_CHECK
-} ConstraintTestType;
-
-typedef struct ConstraintTest
-{
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
-       ConstraintTestType testtype;    /* test type */
-       char       *name;                       /* name of constraint (for error msgs) */
-       char       *domname;            /* name of domain (for error messages) */
-       Node       *check_expr;         /* for CHECK test, a boolean expression */
-} ConstraintTest;
-
-/*
- * Placeholder node for the value to be processed by a domains
- * check constraint.
- */
-typedef struct DomainConstraintValue
-{
-       NodeTag         type;
-} DomainConstraintValue;
-
-typedef struct ConstraintTestValue
-{
-       NodeTag         type;
-       Oid                     typeId;
-       int32           typeMod;
-} ConstraintTestValue;
-
-/*
- * ColumnDef - column definition (used in various creates)
- *
- * If the column has a default value, we may have the value expression
- * in either "raw" form (an untransformed parse tree) or "cooked" form
- * (the nodeToString representation of an executable expression tree),
- * depending on how this ColumnDef node was created (by parsing, or by
- * inheritance from an existing relation).     We should never have both
- * in the same node!
- *
- * The constraints list may contain a CONSTR_DEFAULT item in a raw
- * parsetree produced by gram.y, but transformCreateStmt will remove
- * the item and set raw_default instead.  CONSTR_DEFAULT items
- * should not appear in any subsequent processing.
- *
- * The "support" field, if not null, denotes a supporting relation that
- * should be linked by an internal dependency to the column.  Currently
- * this is only used to link a SERIAL column's sequence to the column.
- */
-typedef struct ColumnDef
-{
-       NodeTag         type;
-       char       *colname;            /* name of column */
-       TypeName   *typename;           /* type of column */
-       int                     inhcount;               /* number of times column is inherited */
-       bool            is_local;               /* column has local (non-inherited) def'n */
-       bool            is_not_null;    /* NOT NULL constraint specified? */
-       Node       *raw_default;        /* default value (untransformed parse
-                                                                * tree) */
-       char       *cooked_default; /* nodeToString representation */
-       List       *constraints;        /* other constraints on column */
-       RangeVar   *support;            /* supporting relation, if any */
-} ColumnDef;
-
-/*
  * FuncCall - a function or aggregate invocation
  *
  * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct
@@ -415,6 +276,15 @@ typedef struct InsertDefault
 } InsertDefault;
 
 /*
+ * Empty node used as raw-parse-tree representation of VALUE keyword
+ * for domain check constraints.
+ */
+typedef struct DomainConstraintValue
+{
+       NodeTag         type;
+} DomainConstraintValue;
+
+/*
  * SortGroupBy - for ORDER BY clause
  */
 typedef struct SortGroupBy
@@ -447,6 +317,40 @@ typedef struct RangeFunction
 } RangeFunction;
 
 /*
+ * ColumnDef - column definition (used in various creates)
+ *
+ * If the column has a default value, we may have the value expression
+ * in either "raw" form (an untransformed parse tree) or "cooked" form
+ * (the nodeToString representation of an executable expression tree),
+ * depending on how this ColumnDef node was created (by parsing, or by
+ * inheritance from an existing relation).     We should never have both
+ * in the same node!
+ *
+ * The constraints list may contain a CONSTR_DEFAULT item in a raw
+ * parsetree produced by gram.y, but transformCreateStmt will remove
+ * the item and set raw_default instead.  CONSTR_DEFAULT items
+ * should not appear in any subsequent processing.
+ *
+ * The "support" field, if not null, denotes a supporting relation that
+ * should be linked by an internal dependency to the column.  Currently
+ * this is only used to link a SERIAL column's sequence to the column.
+ */
+typedef struct ColumnDef
+{
+       NodeTag         type;
+       char       *colname;            /* name of column */
+       TypeName   *typename;           /* type of column */
+       int                     inhcount;               /* number of times column is inherited */
+       bool            is_local;               /* column has local (non-inherited) def'n */
+       bool            is_not_null;    /* NOT NULL constraint specified? */
+       Node       *raw_default;        /* default value (untransformed parse
+                                                                * tree) */
+       char       *cooked_default; /* nodeToString representation */
+       List       *constraints;        /* other constraints on column */
+       RangeVar   *support;            /* supporting relation, if any */
+} ColumnDef;
+
+/*
  * IndexElem - index parameters (used in CREATE INDEX)
  *
  * For a plain index, each 'name' is an attribute name in the heap relation;
@@ -479,21 +383,6 @@ typedef struct DefElem
  *     Nodes for a Query tree
  ****************************************************************************/
 
-/*
- * TargetEntry -
- *        a target  entry (used in the transformed target list)
- *
- * one of resdom or fjoin is not NULL. a target list is
- *             ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
- */
-typedef struct TargetEntry
-{
-       NodeTag         type;
-       Resdom     *resdom;                     /* fjoin overload this to be a list?? */
-       Fjoin      *fjoin;
-       Node       *expr;
-} TargetEntry;
-
 /*--------------------
  * RangeTblEntry -
  *       A range table is a List of RangeTblEntry nodes.
index 097f8d9..67a4d48 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.62 2002/12/05 15:50:39 tgl Exp $
+ * $Id: plannodes.h,v 1.63 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -375,31 +375,4 @@ typedef struct Limit
        Node       *limitCount;         /* COUNT parameter, or NULL if none */
 } Limit;
 
-/* ---------------------
- *             SubPlan node
- *
- * XXX Perhaps does not belong in this file?  It's not really a Plan node.
- * Should we make it inherit from Plan anyway?
- * ---------------------
- */
-typedef struct SubPlan
-{
-       NodeTag         type;
-       Plan       *plan;                       /* subselect plan itself */
-       int                     plan_id;                /* dummy thing because of we haven't equal
-                                                                * funcs for plan nodes... actually, we
-                                                                * could put *plan itself somewhere else
-                                                                * (TopPlan node ?)... */
-       List       *rtable;                     /* range table for subselect */
-       /* setParam and parParam are lists of integers (param IDs) */
-       List       *setParam;           /* non-correlated EXPR & EXISTS subqueries
-                                                                * have to set some Params for paren Plan */
-       List       *parParam;           /* indices of corr. Vars from parent plan */
-       SubLink    *sublink;            /* SubLink node from parser; holds info
-                                                                * about what to do with subselect's
-                                                                * results */
-
-       struct SubPlanState *pstate; /* XXX TEMPORARY HACK */
-} SubPlan;
-
 #endif   /* PLANNODES_H */
index 11e74a8..ec0ad42 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.71 2002/11/30 21:25:06 tgl Exp $
+ * $Id: primnodes.h,v 1.72 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -67,31 +67,6 @@ typedef struct Resdom
                                                                 * from final target list */
 } Resdom;
 
-/*
- * Fjoin
- */
-typedef struct Fjoin
-{
-       NodeTag         type;
-       bool            fj_initialized; /* true if the Fjoin has already been
-                                                                * initialized for the current target list
-                                                                * evaluation */
-       int                     fj_nNodes;              /* The number of Iter nodes returning sets
-                                                                * that the node will flatten */
-       List       *fj_innerNode;       /* exactly one Iter node.  We eval every
-                                                                * node in the outerList once then eval
-                                                                * the inner node to completion pair the
-                                                                * outerList result vector with each inner
-                                                                * result to form the full result.      When
-                                                                * the inner has been exhausted, we get
-                                                                * the next outer result vector and reset
-                                                                * the inner. */
-       DatumPtr        fj_results;             /* The complete (flattened) result vector */
-       BoolPtr         fj_alwaysDone;  /* a null vector to indicate sets with a
-                                                                * cardinality of 0, we treat them as the
-                                                                * set {NULL}. */
-} Fjoin;
-
 
 /*
  * Alias -
@@ -140,96 +115,20 @@ typedef struct RangeVar
  */
 
 /*
- * CoercionContext - distinguishes the allowed set of type casts
+ * Expr - generic superclass for executable-expression nodes
  *
- * NB: ordering of the alternatives is significant; later (larger) values
- * allow more casts than earlier ones.
+ * All node types that are used in executable expression trees should derive
+ * from Expr (that is, have Expr as their first field).  Since Expr only
+ * contains NodeTag, this is a formality, but it is an easy form of
+ * documentation.  See also the ExprState node types in execnodes.h.
  */
-typedef enum CoercionContext
-{
-       COERCION_IMPLICIT,                      /* coercion in context of expression */
-       COERCION_ASSIGNMENT,            /* coercion in context of assignment */
-       COERCION_EXPLICIT                       /* explicit cast operation */
-} CoercionContext;
-
-/*
- * CoercionForm - information showing how to display a function-call node
- */
-typedef enum CoercionForm
-{
-       COERCE_EXPLICIT_CALL,           /* display as a function call */
-       COERCE_EXPLICIT_CAST,           /* display as an explicit cast */
-       COERCE_IMPLICIT_CAST,           /* implicit cast, so hide it */
-       COERCE_DONTCARE                         /* special case for pathkeys */
-} CoercionForm;
-
-/*
- * Expr
- *
- * Note: DISTINCT_EXPR implements the "x IS DISTINCT FROM y" construct.
- * This is similar to an OP_EXPR, except for its handling of NULL inputs.
- * The oper field is always an Oper node for the "=" operator for x and y.
- * (We use "=", not the more obvious "<>", because more datatypes have "="
- * than "<>".  This means the executor must invert the operator result.)
- */
-typedef enum OpType
-{
-       OP_EXPR, DISTINCT_EXPR, FUNC_EXPR,
-       OR_EXPR, AND_EXPR, NOT_EXPR, SUBPLAN_EXPR
-} OpType;
-
 typedef struct Expr
 {
        NodeTag         type;
-       Oid                     typeOid;                /* oid of the type of this expression */
-       OpType          opType;                 /* kind of expression */
-       Node       *oper;                       /* operator node if needed (Oper, Func, or
-                                                                * SubPlan) */
-       List       *args;                       /* arguments to this expression */
 } Expr;
 
 /*
- * Oper - Expr subnode for an OP_EXPR (or DISTINCT_EXPR)
- *
- * NOTE: in the good old days 'opno' used to be both (or either, or
- * neither) the pg_operator oid, and/or the pg_proc oid depending
- * on the postgres module in question (parser->pg_operator,
- * executor->pg_proc, planner->both), the mood of the programmer,
- * and the phase of the moon (rumors that it was also depending on the day
- * of the week are probably false). To make things even more postgres-like
- * (i.e. a mess) some comments were referring to 'opno' using the name
- * 'opid'. Anyway, now we have two separate fields, and of course that
- * immediately removes all bugs from the code...               [ sp :-) ].
- *
- * Note also that opid is not necessarily filled in immediately on creation
- * of the node.  The planner makes sure it is valid before passing the node
- * tree to the executor, but during parsing/planning opid is typically 0.
- */
-typedef struct Oper
-{
-       NodeTag         type;
-       Oid                     opno;                   /* PG_OPERATOR OID of the operator */
-       Oid                     opid;                   /* PG_PROC OID of underlying function */
-       Oid                     opresulttype;   /* PG_TYPE OID of result value */
-       bool            opretset;               /* true if operator returns set */
-       FunctionCachePtr op_fcache; /* runtime state, else NULL */
-} Oper;
-
-/*
- * Func - Expr subnode for a FUNC_EXPR
- */
-typedef struct Func
-{
-       NodeTag         type;
-       Oid                     funcid;                 /* PG_PROC OID of the function */
-       Oid                     funcresulttype; /* PG_TYPE OID of result value */
-       bool            funcretset;             /* true if function returns set */
-       CoercionForm funcformat;        /* how to display this function call */
-       FunctionCachePtr func_fcache;           /* runtime state, or NULL */
-} Func;
-
-/*
- * Var
+ * Var - expression node representing a variable (ie, a table column)
  *
  * Note: during parsing/planning, varnoold/varoattno are always just copies
  * of varno/varattno.  At the tail end of planning, Var nodes appearing in
@@ -248,7 +147,7 @@ typedef struct Func
 
 typedef struct Var
 {
-       NodeTag         type;
+       Expr            xpr;
        Index           varno;                  /* index of this var's relation in the
                                                                 * range table (could also be INNER or
                                                                 * OUTER) */
@@ -272,7 +171,7 @@ typedef struct Var
  */
 typedef struct Const
 {
-       NodeTag         type;
+       Expr            xpr;
        Oid                     consttype;              /* PG_TYPE OID of the constant's datatype */
        int                     constlen;               /* typlen of the constant's datatype */
        Datum           constvalue;             /* the constant's value */
@@ -300,12 +199,11 @@ typedef struct Const
  *
  *             PARAM_EXEC:      The parameter is an internal executor parameter.
  *                             It has a number contained in the `paramid' field.
- *
  * ----------------
  */
 typedef struct Param
 {
-       NodeTag         type;
+       Expr            xpr;
        int                     paramkind;              /* kind of parameter. See above */
        AttrNumber      paramid;                /* numeric ID for parameter ("$1") */
        char       *paramname;          /* name for parameter ("$.foo") */
@@ -317,16 +215,157 @@ typedef struct Param
  */
 typedef struct Aggref
 {
-       NodeTag         type;
+       Expr            xpr;
        Oid                     aggfnoid;               /* pg_proc Oid of the aggregate */
        Oid                     aggtype;                /* type Oid of result of the aggregate */
-       Node       *target;                     /* expression we are aggregating on */
+       Expr       *target;                     /* expression we are aggregating on */
        bool            aggstar;                /* TRUE if argument was really '*' */
        bool            aggdistinct;    /* TRUE if it's agg(DISTINCT ...) */
+
+       /* XXX this should move to AggrefExprState: */
        int                     aggno;                  /* workspace for executor (see nodeAgg.c) */
 } Aggref;
 
 /* ----------------
+ *     ArrayRef: describes an array subscripting operation
+ *
+ * An ArrayRef can describe fetching a single element from an array,
+ * fetching a subarray (array slice), storing a single element into
+ * an array, or storing a slice.  The "store" cases work with an
+ * initial array value and a source value that is inserted into the
+ * appropriate part of the array; the result of the operation is an
+ * entire new modified array value.
+ *
+ * If reflowerindexpr = NIL, then we are fetching or storing a single array
+ * element at the subscripts given by refupperindexpr. Otherwise we are
+ * fetching or storing an array slice, that is a rectangular subarray
+ * with lower and upper bounds given by the index expressions.
+ * reflowerindexpr must be the same length as refupperindexpr when it
+ * is not NIL.
+ *
+ * Note: array types can be fixed-length (refattrlength > 0), but only
+ * when the element type is itself fixed-length.  Otherwise they are
+ * varlena structures and have refattrlength = -1.     In any case,
+ * an array type is never pass-by-value.
+ *
+ * Note: refrestype is NOT the element type, but the array type,
+ * when doing subarray fetch or either type of store.  It might be a good
+ * idea to include a refelemtype field as well.
+ * ----------------
+ */
+typedef struct ArrayRef
+{
+       Expr            xpr;
+       Oid                     refrestype;             /* type of the result of the ArrayRef
+                                                                * operation */
+       int                     refattrlength;  /* typlen of array type */
+       int                     refelemlength;  /* typlen of the array element type */
+       bool            refelembyval;   /* is the element type pass-by-value? */
+       char            refelemalign;   /* typalign of the element type */
+       List       *refupperindexpr;/* expressions that evaluate to upper
+                                                                * array indexes */
+       List       *reflowerindexpr;/* expressions that evaluate to lower
+                                                                * array indexes */
+       Expr       *refexpr;            /* the expression that evaluates to an
+                                                                * array value */
+       Expr       *refassgnexpr;       /* expression for the source value, or
+                                                                * NULL if fetch */
+} ArrayRef;
+
+/*
+ * CoercionContext - distinguishes the allowed set of type casts
+ *
+ * NB: ordering of the alternatives is significant; later (larger) values
+ * allow more casts than earlier ones.
+ */
+typedef enum CoercionContext
+{
+       COERCION_IMPLICIT,                      /* coercion in context of expression */
+       COERCION_ASSIGNMENT,            /* coercion in context of assignment */
+       COERCION_EXPLICIT                       /* explicit cast operation */
+} CoercionContext;
+
+/*
+ * CoercionForm - information showing how to display a function-call node
+ */
+typedef enum CoercionForm
+{
+       COERCE_EXPLICIT_CALL,           /* display as a function call */
+       COERCE_EXPLICIT_CAST,           /* display as an explicit cast */
+       COERCE_IMPLICIT_CAST,           /* implicit cast, so hide it */
+       COERCE_DONTCARE                         /* special case for pathkeys */
+} CoercionForm;
+
+/*
+ * FuncExpr - expression node for a function call
+ */
+typedef struct FuncExpr
+{
+       Expr            xpr;
+       Oid                     funcid;                 /* PG_PROC OID of the function */
+       Oid                     funcresulttype; /* PG_TYPE OID of result value */
+       bool            funcretset;             /* true if function returns set */
+       CoercionForm funcformat;        /* how to display this function call */
+       List       *args;                       /* arguments to the function */
+
+       FunctionCachePtr func_fcache;           /* XXX runtime state, or NULL */
+} FuncExpr;
+
+/*
+ * OpExpr - expression node for an operator invocation
+ *
+ * Semantically, this is essentially the same as a function call.
+ *
+ * Note that opfuncid is not necessarily filled in immediately on creation
+ * of the node.  The planner makes sure it is valid before passing the node
+ * tree to the executor, but during parsing/planning opfuncid is typically 0.
+ */
+typedef struct OpExpr
+{
+       Expr            xpr;
+       Oid                     opno;                   /* PG_OPERATOR OID of the operator */
+       Oid                     opfuncid;               /* PG_PROC OID of underlying function */
+       Oid                     opresulttype;   /* PG_TYPE OID of result value */
+       bool            opretset;               /* true if operator returns set */
+       List       *args;                       /* arguments to the operator (1 or 2) */
+
+       FunctionCachePtr op_fcache; /* XXX runtime state, else NULL */
+} OpExpr;
+
+/*
+ * DistinctExpr - expression node for "x IS DISTINCT FROM y"
+ *
+ * Except for the nodetag, this is represented identically to an OpExpr
+ * referencing the "=" operator for x and y.
+ * We use "=", not the more obvious "<>", because more datatypes have "="
+ * than "<>".  This means the executor must invert the operator result.
+ * Note that the operator function won't be called at all if either input
+ * is NULL, since then the result can be determined directly.
+ */
+typedef OpExpr DistinctExpr;
+
+/*
+ * BoolExpr - expression node for the basic Boolean operators AND, OR, NOT
+ *
+ * Notice the arguments are given as a List.  For NOT, of course the list
+ * must always have exactly one element.  For AND and OR, the executor can
+ * handle any number of arguments.  The parser treats AND and OR as binary
+ * and so it only produces two-element lists, but the optimizer will flatten
+ * trees of AND and OR nodes to produce longer lists when possible.
+ */
+typedef enum BoolExprType
+{
+       AND_EXPR, OR_EXPR, NOT_EXPR
+} BoolExprType;
+
+typedef struct BoolExpr
+{
+       Expr            xpr;
+       BoolExprType boolop;
+       List       *args;                       /* arguments to this expression */
+} BoolExpr;
+
+/* ----------------
  * SubLink
  *
  * A SubLink represents a subselect appearing in an expression, and in some
@@ -348,19 +387,23 @@ typedef struct Aggref
  * depending on the "useor" flag.  ALL and ANY combine the per-row results
  * using AND and OR semantics respectively.
  *
+ * SubLink is classed as an Expr node, but it is not actually executable;
+ * it must be replaced in the expression tree by a SubPlanExpr node during
+ * planning.
+ *
  * NOTE: lefthand and oper have varying meanings depending on where you look
  * in the parse/plan pipeline:
  * 1. gram.y delivers a list of the (untransformed) lefthand expressions in
  *       lefthand, and sets oper to a single A_Expr (not a list!) containing
  *       the string name of the operator, but no arguments.
  * 2. The parser's expression transformation transforms lefthand normally,
- *       and replaces oper with a list of Oper nodes, one per lefthand
+ *       and replaces oper with a list of OpExpr nodes, one per lefthand
  *       expression.  These nodes represent the parser's resolution of exactly
  *       which operator to apply to each pair of lefthand and targetlist
- *       expressions.  However, we have not constructed actual Expr trees for
- *       these operators yet.  This is the representation seen in saved rules
- *       and in the rewriter.
- * 3. Finally, the planner converts the oper list to a list of normal Expr
+ *       expressions.  However, we have not constructed complete Expr trees for
+ *       these operations yet: the args fields of the OpExpr nodes are NIL.
+ *       This is the representation seen in saved rules and in the rewriter.
+ * 3. Finally, the planner converts the oper list to a list of normal OpExpr
  *       nodes representing the application of the operator(s) to the lefthand
  *       expressions and values from the inner targetlist.  The inner
  *       targetlist items are represented by placeholder Param nodes.
@@ -370,7 +413,7 @@ typedef struct Aggref
  * Planner routines that might see either representation 2 or 3 can tell
  * the difference by checking whether lefthand is NIL or not.  Also,
  * representation 2 appears in a "bare" SubLink, while representation 3 is
- * found in SubLinks that are children of SubPlan nodes.
+ * found in SubLinks that are children of SubPlanExpr nodes.
  *
  * In EXISTS and EXPR SubLinks, both lefthand and oper are unused and are
  * always NIL. useor is not significant either for these sublink types.
@@ -384,62 +427,45 @@ typedef enum SubLinkType
 
 typedef struct SubLink
 {
-       NodeTag         type;
+       Expr            xpr;
        SubLinkType subLinkType;        /* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
        bool            useor;                  /* TRUE to combine column results with
                                                                 * "OR" not "AND" */
        List       *lefthand;           /* list of outer-query expressions on the
                                                                 * left */
-       List       *oper;                       /* list of Oper nodes for combining
-                                                                * operators */
+       List       *oper;                       /* list of OpExpr nodes for combining
+                                                                * operators, or final list of executable
+                                                                * expressions */
        Node       *subselect;          /* subselect as Query* or parsetree */
 } SubLink;
 
-/* ----------------
- *     ArrayRef: describes an array subscripting operation
- *
- * An ArrayRef can describe fetching a single element from an array,
- * fetching a subarray (array slice), storing a single element into
- * an array, or storing a slice.  The "store" cases work with an
- * initial array value and a source value that is inserted into the
- * appropriate part of the array; the result of the operation is an
- * entire new modified array value.
- *
- * If reflowerindexpr = NIL, then we are fetching or storing a single array
- * element at the subscripts given by refupperindexpr. Otherwise we are
- * fetching or storing an array slice, that is a rectangular subarray
- * with lower and upper bounds given by the index expressions.
- * reflowerindexpr must be the same length as refupperindexpr when it
- * is not NIL.
- *
- * Note: array types can be fixed-length (refattrlength > 0), but only
- * when the element type is itself fixed-length.  Otherwise they are
- * varlena structures and have refattrlength = -1.     In any case,
- * an array type is never pass-by-value.
+/*
+ * SubPlanExpr - executable expression node for a subplan (sub-SELECT)
  *
- * Note: refrestype is NOT the element type, but the array type,
- * when doing subarray fetch or either type of store.  It might be a good
- * idea to include a refelemtype field as well.
- * ----------------
+ * The planner replaces SubLink nodes in expression trees with SubPlanExpr
+ * nodes after it has finished planning the subquery.  See notes above.
  */
-typedef struct ArrayRef
+typedef struct SubPlanExpr
 {
-       NodeTag         type;
-       Oid                     refrestype;             /* type of the result of the ArrayRef
-                                                                * operation */
-       int                     refattrlength;  /* typlen of array type */
-       int                     refelemlength;  /* typlen of the array element type */
-       bool            refelembyval;   /* is the element type pass-by-value? */
-       char            refelemalign;   /* typalign of the element type */
-       List       *refupperindexpr;/* expressions that evaluate to upper
-                                                                * array indexes */
-       List       *reflowerindexpr;/* expressions that evaluate to lower
-                                                                * array indexes */
-       Node       *refexpr;            /* the expression that evaluates to an
-                                                                * array value */
-       Node       *refassgnexpr;       /* expression for the source value, or
-                                                                * NULL if fetch */
-} ArrayRef;
+       Expr            xpr;
+       Oid                     typeOid;                /* PG_TYPE OID of the expression result */
+       struct Plan *plan;                      /* subselect plan itself */
+       int                     plan_id;                /* dummy thing because of we haven't equal
+                                                                * funcs for plan nodes... actually, we
+                                                                * could put *plan itself somewhere else
+                                                                * (TopPlan node ?)... */
+       List       *rtable;                     /* range table for subselect */
+       /* setParam and parParam are lists of integers (param IDs) */
+       List       *setParam;           /* non-correlated EXPR & EXISTS subqueries
+                                                                * have to set some Params for paren Plan */
+       List       *parParam;           /* indices of input Params from parent plan */
+       List       *args;                       /* exprs to pass as parParam values */
+       SubLink    *sublink;            /* SubLink node from parser; holds info
+                                                                * about what to do with subselect's
+                                                                * results */
+
+       struct SubPlanState *pstate; /* XXX TEMPORARY HACK */
+} SubPlanExpr;
 
 /* ----------------
  * FieldSelect
@@ -453,8 +479,8 @@ typedef struct ArrayRef
 
 typedef struct FieldSelect
 {
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
        AttrNumber      fieldnum;               /* attribute number of field to extract */
        Oid                     resulttype;             /* type of the field (result type of this
                                                                 * node) */
@@ -476,13 +502,134 @@ typedef struct FieldSelect
 
 typedef struct RelabelType
 {
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
        Oid                     resulttype;             /* output type of coercion expression */
        int32           resulttypmod;   /* output typmod (usually -1) */
        CoercionForm relabelformat;     /* how to display this node */
 } RelabelType;
 
+/*
+ * CaseExpr - a CASE expression
+ */
+typedef struct CaseExpr
+{
+       Expr            xpr;
+       Oid                     casetype;               /* type of expression result */
+       Expr       *arg;                        /* implicit equality comparison argument */
+       List       *args;                       /* the arguments (list of WHEN clauses) */
+       Expr       *defresult;          /* the default result (ELSE clause) */
+} CaseExpr;
+
+/*
+ * CaseWhen - an argument to a CASE expression
+ */
+typedef struct CaseWhen
+{
+       Expr            xpr;
+       Expr       *expr;                       /* condition expression */
+       Expr       *result;                     /* substitution result */
+} CaseWhen;
+
+/* ----------------
+ * NullTest
+ *
+ * NullTest represents the operation of testing a value for NULLness.
+ * Currently, we only support scalar input values, but eventually a
+ * row-constructor input should be supported.
+ * The appropriate test is performed and returned as a boolean Datum.
+ * ----------------
+ */
+
+typedef enum NullTestType
+{
+       IS_NULL, IS_NOT_NULL
+} NullTestType;
+
+typedef struct NullTest
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       NullTestType nulltesttype;      /* IS NULL, IS NOT NULL */
+} NullTest;
+
+/*
+ * BooleanTest
+ *
+ * BooleanTest represents the operation of determining whether a boolean
+ * is TRUE, FALSE, or UNKNOWN (ie, NULL).  All six meaningful combinations
+ * are supported.  Note that a NULL input does *not* cause a NULL result.
+ * The appropriate test is performed and returned as a boolean Datum.
+ */
+
+typedef enum BoolTestType
+{
+       IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN
+} BoolTestType;
+
+typedef struct BooleanTest
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       BoolTestType booltesttype;      /* test type */
+} BooleanTest;
+
+/*
+ * ConstraintTest
+ *
+ * ConstraintTest represents the operation of testing a value to see whether
+ * it meets a constraint.  If so, the input value is returned as the result;
+ * if not, an error is raised.
+ */
+
+typedef enum ConstraintTestType
+{
+       CONSTR_TEST_NOTNULL,
+       CONSTR_TEST_CHECK
+} ConstraintTestType;
+
+typedef struct ConstraintTest
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       ConstraintTestType testtype;    /* test type */
+       char       *name;                       /* name of constraint (for error msgs) */
+       char       *domname;            /* name of domain (for error messages) */
+       Expr       *check_expr;         /* for CHECK test, a boolean expression */
+} ConstraintTest;
+
+/*
+ * Placeholder node for the value to be processed by a domains
+ * check constraint.  This is effectively like a Param; could we use
+ * a Param node instead?
+ */
+typedef struct ConstraintTestValue
+{
+       Expr            xpr;
+       Oid                     typeId;
+       int32           typeMod;
+} ConstraintTestValue;
+
+
+/*
+ * TargetEntry -
+ *        a target entry (used in query target lists)
+ *
+ * Strictly speaking, a TargetEntry isn't an expression node (since it can't
+ * be evaluated by ExecEvalExpr).  But we treat it as one anyway, since in
+ * very many places it's convenient to process a whole query targetlist as a
+ * single expression tree.
+ *
+ * The separation between TargetEntry and Resdom is historical.  One of these
+ * days, Resdom should probably get folded into TargetEntry.
+ */
+typedef struct TargetEntry
+{
+       Expr            xpr;
+       Resdom     *resdom;                     /* descriptor for targetlist item */
+       Expr       *expr;                       /* expression to evaluate */
+} TargetEntry;
+
 
 /* ----------------------------------------------------------------
  *                                     node types for join trees
index 333ca0b..6da4768 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: relation.h,v 1.73 2002/12/05 15:50:39 tgl Exp $
+ * $Id: relation.h,v 1.74 2002/12/12 15:49:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -295,7 +295,7 @@ typedef struct PathKeyItem
 
        /*
         * key typically points to a Var node, ie a relation attribute, but it
-        * can also point to a Func clause representing the value indexed by a
+        * can also point to a FuncExpr clause representing the value indexed by a
         * functional index.  Someday we might allow arbitrary expressions as
         * path keys, so don't assume more than you must.
         */
index da0fe4c..8da7a86 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: clauses.h,v 1.56 2002/12/01 21:05:14 tgl Exp $
+ * $Id: clauses.h,v 1.57 2002/12/12 15:49:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "nodes/relation.h"
 
-extern Expr *make_clause(int type, Node *oper, List *args);
 
-extern bool is_opclause(Node *clause);
-extern Expr *make_opclause(Oper *op, Var *leftop, Var *rightop);
+
+#define is_opclause(clause)            ((clause) != NULL && IsA(clause, OpExpr))
+#define is_funcclause(clause)  ((clause) != NULL && IsA(clause, FuncExpr))
+#define is_subplan(clause)             ((clause) != NULL && IsA(clause, SubPlanExpr))
+
+
+extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
+                                                  Expr *leftop, Expr *rightop);
 extern Var *get_leftop(Expr *clause);
 extern Var *get_rightop(Expr *clause);
 
-extern bool is_funcclause(Node *clause);
-extern Expr *make_funcclause(Func *func, List *funcargs);
-
-extern bool or_clause(Node *clause);
-extern Expr *make_orclause(List *orclauses);
+extern Expr *make_funcclause(Oid funcid, Oid funcresulttype, bool funcretset,
+                                                        CoercionForm funcformat, List *funcargs);
 
 extern bool not_clause(Node *clause);
 extern Expr *make_notclause(Expr *notclause);
 extern Expr *get_notclausearg(Expr *notclause);
 
+extern bool or_clause(Node *clause);
+extern Expr *make_orclause(List *orclauses);
+
 extern bool and_clause(Node *clause);
 extern Expr *make_andclause(List *andclauses);
 extern Node *make_and_qual(Node *qual1, Node *qual2);
@@ -60,7 +65,7 @@ extern bool has_distinct_on_clause(Query *query);
 
 extern void clause_get_relids_vars(Node *clause, Relids *relids, List **vars);
 extern int     NumRelids(Node *clause);
-extern void CommuteClause(Expr *clause);
+extern void CommuteClause(OpExpr *clause);
 
 extern Node *eval_const_expressions(Node *node);
 
@@ -78,8 +83,4 @@ extern bool query_tree_walker(Query *query, bool (*walker) (),
 extern void query_tree_mutator(Query *query, Node *(*mutator) (),
                                                           void *context, int flags);
 
-#define is_subplan(clause)     ((clause) != NULL && \
-                                                        IsA(clause, Expr) && \
-                                                        ((Expr *) (clause))->opType == SUBPLAN_EXPR)
-
 #endif   /* CLAUSES_H */
index b03ce04..06f585f 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: paths.h,v 1.61 2002/11/24 21:52:15 tgl Exp $
+ * $Id: paths.h,v 1.62 2002/12/12 15:49:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,8 +42,6 @@ extern void debug_print_rel(Query *root, RelOptInfo *rel);
 extern void create_index_paths(Query *root, RelOptInfo *rel);
 extern Path *best_inner_indexscan(Query *root, RelOptInfo *rel,
                                                                  Relids outer_relids, JoinType jointype);
-extern Oid indexable_operator(Expr *clause, Oid opclass,
-                                  bool indexkey_on_left);
 extern List *extract_or_indexqual_conditions(RelOptInfo *rel,
                                                                IndexOptInfo *index,
                                                                Expr *orsubclause);
index ecd7bca..134adad 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: planmain.h,v 1.63 2002/11/21 00:42:19 tgl Exp $
+ * $Id: planmain.h,v 1.64 2002/12/12 15:49:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,6 +68,6 @@ extern void set_plan_references(Plan *plan, List *rtable);
 extern List *join_references(List *clauses, List *rtable,
                                List *outer_tlist, List *inner_tlist,
                                Index acceptable_rel);
-extern void fix_opids(Node *node);
+extern void fix_opfuncids(Node *node);
 
 #endif   /* PLANMAIN_H */
index 007a3ff..23d4572 100644 (file)
@@ -3,7 +3,7 @@
  *                       procedural language
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.72 2002/12/05 15:50:39 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.73 2002/12/12 15:49:42 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -3499,44 +3499,130 @@ exec_cast_value(Datum value, Oid valtype,
 static bool
 exec_simple_check_node(Node *node)
 {
+       if (node == NULL)
+               return TRUE;
+
        switch (nodeTag(node))
        {
-               case T_Expr:
+               case T_Const:
+                       return TRUE;
+
+               case T_Param:
+                       return TRUE;
+
+               case T_ArrayRef:
                        {
-                               Expr       *expr = (Expr *) node;
-                               List       *l;
+                               ArrayRef   *expr = (ArrayRef *) node;
 
-                               switch (expr->opType)
-                               {
-                                       case OP_EXPR:
-                                       case DISTINCT_EXPR:
-                                       case FUNC_EXPR:
-                                       case OR_EXPR:
-                                       case AND_EXPR:
-                                       case NOT_EXPR:
-                                               break;
+                               if (!exec_simple_check_node((Node *) expr->refupperindexpr))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->reflowerindexpr))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->refexpr))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->refassgnexpr))
+                                       return FALSE;
 
-                                       default:
-                                               return FALSE;
-                               }
+                               return TRUE;
+                       }
 
-                               foreach(l, expr->args)
-                               {
-                                       if (!exec_simple_check_node(lfirst(l)))
-                                               return FALSE;
-                               }
+               case T_FuncExpr:
+                       {
+                               FuncExpr   *expr = (FuncExpr *) node;
+
+                               if (expr->funcretset)
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->args))
+                                       return FALSE;
 
                                return TRUE;
                        }
 
-               case T_Param:
-                       return TRUE;
+               case T_OpExpr:
+                       {
+                               OpExpr     *expr = (OpExpr *) node;
 
-               case T_Const:
-                       return TRUE;
+                               if (expr->opretset)
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->args))
+                                       return FALSE;
+
+                               return TRUE;
+                       }
+
+               case T_DistinctExpr:
+                       {
+                               DistinctExpr *expr = (DistinctExpr *) node;
+
+                               if (expr->opretset)
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->args))
+                                       return FALSE;
+
+                               return TRUE;
+                       }
+
+               case T_BoolExpr:
+                       {
+                               BoolExpr   *expr = (BoolExpr *) node;
+
+                               if (!exec_simple_check_node((Node *) expr->args))
+                                       return FALSE;
+
+                               return TRUE;
+                       }
+
+               case T_FieldSelect:
+                       return exec_simple_check_node((Node *) ((FieldSelect *) node)->arg);
 
                case T_RelabelType:
-                       return exec_simple_check_node(((RelabelType *) node)->arg);
+                       return exec_simple_check_node((Node *) ((RelabelType *) node)->arg);
+
+               case T_CaseExpr:
+                       {
+                               CaseExpr   *expr = (CaseExpr *) node;
+
+                               if (!exec_simple_check_node((Node *) expr->arg))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->args))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->defresult))
+                                       return FALSE;
+
+                               return TRUE;
+                       }
+
+               case T_CaseWhen:
+                       {
+                               CaseWhen   *when = (CaseWhen *) node;
+
+                               if (!exec_simple_check_node((Node *) when->expr))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) when->result))
+                                       return FALSE;
+
+                               return TRUE;
+                       }
+
+               case T_NullTest:
+                       return exec_simple_check_node((Node *) ((NullTest *) node)->arg);
+
+               case T_BooleanTest:
+                       return exec_simple_check_node((Node *) ((BooleanTest *) node)->arg);
+
+               case T_List:
+                       {
+                               List       *expr = (List *) node;
+                               List       *l;
+
+                               foreach(l, expr)
+                               {
+                                       if (!exec_simple_check_node(lfirst(l)))
+                                               return FALSE;
+                               }
+
+                               return TRUE;
+                       }
 
                default:
                        return FALSE;
@@ -3596,18 +3682,17 @@ exec_simple_check_plan(PLpgSQL_expr * expr)
        tle = (TargetEntry *) lfirst(plan->targetlist);
 
        /*
-        * 5. Check that all the nodes in the expression are one of Expr,
-        * Param or Const.
+        * 5. Check that all the nodes in the expression are non-scary.
         */
-       if (!exec_simple_check_node(tle->expr))
+       if (!exec_simple_check_node((Node *) tle->expr))
                return;
 
        /*
         * Yes - this is a simple expression. Remember the expression and the
         * return type
         */
-       expr->plan_simple_expr = tle->expr;
-       expr->plan_simple_type = exprType(tle->expr);
+       expr->plan_simple_expr = (Node *) tle->expr;
+       expr->plan_simple_type = exprType((Node *) tle->expr);
 }
 
 /*