mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Phase 2 of read-only-plans project: restructure expression-tree nodes
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.
This commit is contained in:
@@ -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))
|
||||
|
@@ -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
|
||||
@@ -1602,11 +1602,6 @@ AddRelationRawConstraints(Relation rel,
|
||||
*/
|
||||
expr = (Node *) make_ands_implicit((Expr *) expr);
|
||||
|
||||
/*
|
||||
* Must fix opids in operator clauses.
|
||||
*/
|
||||
fix_opids(expr);
|
||||
|
||||
/*
|
||||
* OK, store it.
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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",
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
/*
|
||||
* 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);
|
||||
/* 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)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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)
|
||||
{
|
||||
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
|
||||
{
|
||||
#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;
|
||||
resjunk = resdom->resjunk;
|
||||
if (!resjunk)
|
||||
{
|
||||
resdom = tle->resdom;
|
||||
expr = tle->expr;
|
||||
resjunk = resdom->resjunk;
|
||||
if (!resjunk)
|
||||
{
|
||||
cleanMap[cleanResno - 1] = resdom->resno;
|
||||
cleanResno++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
ExecInitExpr((Node *) opexpr->args, parent);
|
||||
}
|
||||
break;
|
||||
case T_DistinctExpr:
|
||||
{
|
||||
DistinctExpr *distinctexpr = (DistinctExpr *) node;
|
||||
|
||||
/* 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 *) 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;
|
||||
|
||||
values[resind] = ExecEvalExpr((Node *) tle->expr,
|
||||
econtext,
|
||||
&isNull,
|
||||
&itemIsDone[resind]);
|
||||
nulls[resind] = isNull ? 'n' : ' ';
|
||||
|
||||
if (itemIsDone[resind] != ExprSingleResult)
|
||||
{
|
||||
resind = tle->resdom->resno - 1;
|
||||
|
||||
values[resind] = ExecEvalExpr(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 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;
|
||||
}
|
||||
/* we have undone sets in the tlist, set flag */
|
||||
*isDone = ExprMultipleResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#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)
|
||||
else
|
||||
{
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
newTuple = NULL;
|
||||
goto exit;
|
||||
/* we have done sets in the tlist, set flag for that */
|
||||
haveDoneSets = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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))
|
||||
{
|
||||
Node *outernode = lfirst(fjTlist);
|
||||
|
||||
fjRes = (Resdom *) outernode->iterexpr;
|
||||
resind = fjRes->resno - 1;
|
||||
values[resind] = results[curNode];
|
||||
nulls[resind] = fjIsNull[curNode] ? 'n' : ' ';
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
Resdom *resdom = tle->resdom;
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
TupleDescInitEntry(typeInfo,
|
||||
resdom->resno,
|
||||
resdom->resname,
|
||||
resdom->restype,
|
||||
resdom->restypmod,
|
||||
0,
|
||||
false);
|
||||
}
|
||||
|
||||
return typeInfo;
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
<op->opno,
|
||||
>op->opno,
|
||||
<op->opid,
|
||||
>op->opid);
|
||||
<op->opfuncid,
|
||||
>op->opfuncid);
|
||||
ltop->op_fcache = NULL;
|
||||
gtop->op_fcache = NULL;
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
@@ -678,25 +646,6 @@ _copyVar(Var *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _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
|
||||
*/
|
||||
@@ -748,25 +697,6 @@ _copyParam(Param *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _copyFunc
|
||||
*/
|
||||
static Func *
|
||||
_copyFunc(Func *from)
|
||||
{
|
||||
Func *newnode = makeNode(Func);
|
||||
|
||||
COPY_SCALAR_FIELD(funcid);
|
||||
COPY_SCALAR_FIELD(funcresulttype);
|
||||
COPY_SCALAR_FIELD(funcretset);
|
||||
COPY_SCALAR_FIELD(funcformat);
|
||||
|
||||
/* Do not copy the run-time state, if any */
|
||||
newnode->func_fcache = NULL;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _copyAggref
|
||||
*/
|
||||
@@ -780,7 +710,102 @@ _copyAggref(Aggref *from)
|
||||
COPY_NODE_FIELD(target);
|
||||
COPY_SCALAR_FIELD(aggstar);
|
||||
COPY_SCALAR_FIELD(aggdistinct);
|
||||
COPY_SCALAR_FIELD(aggno); /* probably not necessary */
|
||||
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;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _copyOpExpr
|
||||
*/
|
||||
static OpExpr *
|
||||
_copyOpExpr(OpExpr *from)
|
||||
{
|
||||
OpExpr *newnode = makeNode(OpExpr);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -802,6 +827,26 @@ _copySubLink(SubLink *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _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
|
||||
*/
|
||||
@@ -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",
|
||||
|
@@ -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"
|
||||
|
||||
@@ -98,18 +97,6 @@ _equalResdom(Resdom *a, Resdom *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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)
|
||||
@@ -161,28 +140,6 @@ _equalVar(Var *a, Var *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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;
|
||||
}
|
||||
@@ -270,6 +295,21 @@ _equalSubLink(SubLink *a, SubLink *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -299,6 +339,74 @@ _equalRelabelType(RelabelType *a, RelabelType *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
|
||||
_equalConstraintTestValue(ConstraintTestValue *a, ConstraintTestValue *b)
|
||||
{
|
||||
COMPARE_SCALAR_FIELD(typeId);
|
||||
COMPARE_SCALAR_FIELD(typeMod);
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -331,39 +439,6 @@ _equalFromExpr(FromExpr *a, FromExpr *b)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Stuff from plannodes.h
|
||||
*/
|
||||
|
||||
static bool
|
||||
_equalSubPlan(SubPlan *a, SubPlan *b)
|
||||
{
|
||||
/* should compare plans, but have to settle for comparing plan IDs */
|
||||
COMPARE_SCALAR_FIELD(plan_id);
|
||||
|
||||
COMPARE_NODE_FIELD(rtable);
|
||||
COMPARE_NODE_FIELD(sublink);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Stuff from relation.h
|
||||
@@ -573,6 +648,12 @@ _equalInsertDefault(InsertDefault *a, InsertDefault *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalDomainConstraintValue(DomainConstraintValue *a, DomainConstraintValue *b)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
|
||||
{
|
||||
@@ -1340,16 +1421,6 @@ _equalDefElem(DefElem *a, DefElem *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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;
|
||||
|
@@ -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"
|
||||
|
||||
@@ -49,30 +52,9 @@ makeSimpleA_Expr(int oper, const char *name,
|
||||
return a;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
@@ -188,6 +170,21 @@ makeNullConst(Oid consttype)
|
||||
typByVal);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
@@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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");
|
||||
|
@@ -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();
|
||||
}
|
||||
@@ -357,27 +349,6 @@ _readVar(void)
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _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
|
||||
*/
|
||||
@@ -400,42 +371,6 @@ _readConst(void)
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readFunc
|
||||
*/
|
||||
static Func *
|
||||
_readFunc(void)
|
||||
{
|
||||
READ_LOCALS(Func);
|
||||
|
||||
READ_OID_FIELD(funcid);
|
||||
READ_OID_FIELD(funcresulttype);
|
||||
READ_BOOL_FIELD(funcretset);
|
||||
READ_ENUM_FIELD(funcformat, CoercionForm);
|
||||
|
||||
local_node->func_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readOper
|
||||
*/
|
||||
static Oper *
|
||||
_readOper(void)
|
||||
{
|
||||
READ_LOCALS(Oper);
|
||||
|
||||
READ_OID_FIELD(opno);
|
||||
READ_OID_FIELD(opid);
|
||||
READ_OID_FIELD(opresulttype);
|
||||
READ_BOOL_FIELD(opretset);
|
||||
|
||||
local_node->op_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readParam
|
||||
*/
|
||||
@@ -465,24 +400,129 @@ _readAggref(void)
|
||||
READ_NODE_FIELD(target);
|
||||
READ_BOOL_FIELD(aggstar);
|
||||
READ_BOOL_FIELD(aggdistinct);
|
||||
/* aggno is not saved since it is just executor state */
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
static RangeVar *
|
||||
_readRangeVar(void)
|
||||
/*
|
||||
* _readArrayRef
|
||||
*/
|
||||
static ArrayRef *
|
||||
_readArrayRef(void)
|
||||
{
|
||||
READ_LOCALS(RangeVar);
|
||||
READ_LOCALS(ArrayRef);
|
||||
|
||||
local_node->catalogname = NULL; /* not currently saved in output
|
||||
* format */
|
||||
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_STRING_FIELD(schemaname);
|
||||
READ_STRING_FIELD(relname);
|
||||
READ_ENUM_FIELD(inhOpt, InhOption);
|
||||
READ_BOOL_FIELD(istemp);
|
||||
READ_NODE_FIELD(alias);
|
||||
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;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readOpExpr
|
||||
*/
|
||||
static OpExpr *
|
||||
_readOpExpr(void)
|
||||
{
|
||||
READ_LOCALS(OpExpr);
|
||||
|
||||
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;
|
||||
|
||||
READ_OID_FIELD(opresulttype);
|
||||
READ_BOOL_FIELD(opretset);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
local_node->op_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readDistinctExpr
|
||||
*/
|
||||
static DistinctExpr *
|
||||
_readDistinctExpr(void)
|
||||
{
|
||||
READ_LOCALS(DistinctExpr);
|
||||
|
||||
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;
|
||||
|
||||
READ_OID_FIELD(opresulttype);
|
||||
READ_BOOL_FIELD(opretset);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
local_node->op_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readBoolExpr
|
||||
*/
|
||||
static BoolExpr *
|
||||
_readBoolExpr(void)
|
||||
{
|
||||
READ_LOCALS(BoolExpr);
|
||||
|
||||
/* 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_NODE_FIELD(args);
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
@@ -504,6 +544,10 @@ _readSubLink(void)
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readSubPlanExpr is not needed since it doesn't appear in stored rules.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _readFieldSelect
|
||||
*/
|
||||
@@ -536,58 +580,6 @@ _readRelabelType(void)
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _readCaseExpr
|
||||
*/
|
||||
@@ -663,17 +655,6 @@ _readConstraintTest(void)
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readDomainConstraintValue
|
||||
*/
|
||||
static DomainConstraintValue *
|
||||
_readDomainConstraintValue(void)
|
||||
{
|
||||
READ_LOCALS_NO_FIELDS(DomainConstraintValue);
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readConstraintTestValue
|
||||
*/
|
||||
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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,22 +514,9 @@ 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;
|
||||
|
||||
while (*indexkeys != 0)
|
||||
{
|
||||
funcargs = lappend(funcargs,
|
||||
find_indexkey_var(root, rel, *indexkeys));
|
||||
indexkeys++;
|
||||
}
|
||||
|
||||
sortop = *ordering;
|
||||
if (ScanDirectionIsBackward(scandir))
|
||||
{
|
||||
@@ -538,9 +525,21 @@ build_index_pathkeys(Query *root,
|
||||
return NIL; /* oops, no reverse sort operator? */
|
||||
}
|
||||
|
||||
while (*indexkeys != 0)
|
||||
{
|
||||
funcargs = lappend(funcargs,
|
||||
find_indexkey_var(root, rel, *indexkeys));
|
||||
indexkeys++;
|
||||
}
|
||||
|
||||
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
|
||||
|
@@ -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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -27,15 +27,14 @@
|
||||
|
||||
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
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -502,17 +502,6 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
|
||||
elog(ERROR, "cannot use aggregate function in FROM function expression");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
FuncExpr *funcexpr;
|
||||
|
||||
funcnode = makeNode(Func);
|
||||
funcnode->funcid = funcid;
|
||||
funcnode->funcresulttype = rettype;
|
||||
funcnode->funcretset = false; /* only possible case here */
|
||||
funcnode->funcformat = fformat;
|
||||
funcnode->func_fcache = NULL;
|
||||
funcexpr = makeNode(FuncExpr);
|
||||
funcexpr->funcid = funcid;
|
||||
funcexpr->funcresulttype = rettype;
|
||||
funcexpr->funcretset = false; /* only possible case here */
|
||||
funcexpr->funcformat = fformat;
|
||||
funcexpr->args = args;
|
||||
|
||||
expr = makeNode(Expr);
|
||||
expr->typeOid = rettype;
|
||||
expr->opType = FUNC_EXPR;
|
||||
expr->oper = (Node *) funcnode;
|
||||
expr->args = args;
|
||||
|
||||
return (Node *) expr;
|
||||
return (Node *) funcexpr;
|
||||
}
|
||||
|
@@ -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;
|
||||
break;
|
||||
case T_Aggref:
|
||||
type = ((Aggref *) expr)->aggtype;
|
||||
break;
|
||||
case T_Param:
|
||||
type = ((Param *) expr)->paramtype;
|
||||
break;
|
||||
case T_FieldSelect:
|
||||
type = ((FieldSelect *) expr)->resulttype;
|
||||
case T_Aggref:
|
||||
type = ((Aggref *) expr)->aggtype;
|
||||
break;
|
||||
case T_RelabelType:
|
||||
type = ((RelabelType *) expr)->resulttype;
|
||||
case T_ArrayRef:
|
||||
type = ((ArrayRef *) expr)->refrestype;
|
||||
break;
|
||||
case T_FuncExpr:
|
||||
type = ((FuncExpr *) expr)->funcresulttype;
|
||||
break;
|
||||
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)
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
case PARAM_NAMED:
|
||||
appendStringInfo(buf, "$%s", param->paramname);
|
||||
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, ')');
|
||||
case PARAM_NUM:
|
||||
case PARAM_EXEC:
|
||||
appendStringInfo(buf, "$%d", param->paramid);
|
||||
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, ')');
|
||||
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)");
|
||||
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;
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user