mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Phase 3 of read-only-plans project: ExecInitExpr now builds expression
execution state trees, and ExecEvalExpr takes an expression state tree not an expression plan tree. The plan tree is now read-only as far as the executor is concerned. Next step is to begin actually exploiting this property.
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/bootstrap/bootstrap.c,v 1.145 2002/11/14 23:53:27 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.146 2002/12/13 19:45:45 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "executor/executor.h"
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/ipc.h"
|
||||
@@ -1142,6 +1143,8 @@ index_register(Oid heap,
|
||||
/* predicate will likely be null, but may as well copy it */
|
||||
newind->il_info->ii_Predicate = (List *)
|
||||
copyObject(indexInfo->ii_Predicate);
|
||||
newind->il_info->ii_PredicateState = (List *)
|
||||
ExecInitExpr((Expr *) newind->il_info->ii_Predicate, NULL);
|
||||
|
||||
newind->il_next = ILHead;
|
||||
ILHead = newind;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.206 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.207 2002/12/13 19:45:47 tgl Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@@ -912,6 +912,7 @@ BuildIndexInfo(Form_pg_index indexStruct)
|
||||
|
||||
/*
|
||||
* If partial index, convert predicate into expression nodetree
|
||||
* and prepare an execution state nodetree for it
|
||||
*/
|
||||
if (VARSIZE(&indexStruct->indpred) > VARHDRSZ)
|
||||
{
|
||||
@@ -921,10 +922,15 @@ BuildIndexInfo(Form_pg_index indexStruct)
|
||||
PointerGetDatum(&indexStruct->indpred)));
|
||||
ii->ii_Predicate = stringToNode(predString);
|
||||
fix_opfuncids((Node *) ii->ii_Predicate);
|
||||
ii->ii_PredicateState = (List *)
|
||||
ExecInitExpr((Expr *) ii->ii_Predicate, NULL);
|
||||
pfree(predString);
|
||||
}
|
||||
else
|
||||
{
|
||||
ii->ii_Predicate = NIL;
|
||||
ii->ii_PredicateState = NIL;
|
||||
}
|
||||
|
||||
/* Other info */
|
||||
ii->ii_Unique = indexStruct->indisunique;
|
||||
@@ -1483,7 +1489,7 @@ IndexBuildHeapScan(Relation heapRelation,
|
||||
Datum attdata[INDEX_MAX_KEYS];
|
||||
char nulls[INDEX_MAX_KEYS];
|
||||
double reltuples;
|
||||
List *predicate = indexInfo->ii_Predicate;
|
||||
List *predicate = indexInfo->ii_PredicateState;
|
||||
TupleTable tupleTable;
|
||||
TupleTableSlot *slot;
|
||||
ExprContext *econtext;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.185 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.186 2002/12/13 19:45:48 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -758,7 +758,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
num_defaults;
|
||||
FmgrInfo *in_functions;
|
||||
Oid *elements;
|
||||
Node **constraintexprs;
|
||||
ExprState **constraintexprs;
|
||||
bool hasConstraints = false;
|
||||
int i;
|
||||
List *cur;
|
||||
@@ -772,7 +772,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
TupleTableSlot *slot;
|
||||
bool file_has_oids;
|
||||
int *defmap;
|
||||
Node **defexprs; /* array of default att expressions */
|
||||
ExprState **defexprs; /* array of default att expressions */
|
||||
ExprContext *econtext; /* used for ExecEvalExpr for default atts */
|
||||
MemoryContext oldcontext = CurrentMemoryContext;
|
||||
|
||||
@@ -812,8 +812,8 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
|
||||
elements = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
|
||||
defmap = (int *) palloc(num_phys_attrs * sizeof(int));
|
||||
defexprs = (Node **) palloc(num_phys_attrs * sizeof(Node *));
|
||||
constraintexprs = (Node **) palloc0(num_phys_attrs * sizeof(Node *));
|
||||
defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
|
||||
constraintexprs = (ExprState **) palloc0(num_phys_attrs * sizeof(ExprState *));
|
||||
|
||||
for (i = 0; i < num_phys_attrs; i++)
|
||||
{
|
||||
@@ -837,10 +837,12 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
{
|
||||
/* attribute is NOT to be copied */
|
||||
/* use default value if one exists */
|
||||
defexprs[num_defaults] = build_column_default(rel, i + 1);
|
||||
if (defexprs[num_defaults] != NULL)
|
||||
Node *defexpr = build_column_default(rel, i + 1);
|
||||
|
||||
if (defexpr != NULL)
|
||||
{
|
||||
fix_opfuncids(defexprs[num_defaults]);
|
||||
fix_opfuncids(defexpr);
|
||||
defexprs[num_defaults] = ExecInitExpr((Expr *) defexpr, NULL);
|
||||
defmap[num_defaults] = i;
|
||||
num_defaults++;
|
||||
}
|
||||
@@ -872,7 +874,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
if (node != (Node *) prm)
|
||||
{
|
||||
fix_opfuncids(node);
|
||||
constraintexprs[i] = node;
|
||||
constraintexprs[i] = ExecInitExpr((Expr *) node, NULL);
|
||||
hasConstraints = true;
|
||||
}
|
||||
}
|
||||
@@ -1165,10 +1167,10 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
|
||||
for (i = 0; i < num_phys_attrs; i++)
|
||||
{
|
||||
Node *node = constraintexprs[i];
|
||||
ExprState *exprstate = constraintexprs[i];
|
||||
bool isnull;
|
||||
|
||||
if (node == NULL)
|
||||
if (exprstate == NULL)
|
||||
continue; /* no constraint for this attr */
|
||||
|
||||
/* Insert current row's value into the Param value */
|
||||
@@ -1180,7 +1182,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
|
||||
* to replace the value (consider e.g. a timestamp precision
|
||||
* restriction).
|
||||
*/
|
||||
values[i] = ExecEvalExpr(node, econtext,
|
||||
values[i] = ExecEvalExpr(exprstate, econtext,
|
||||
&isnull, NULL);
|
||||
nulls[i] = isnull ? 'n' : ' ';
|
||||
}
|
||||
|
@@ -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.96 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.97 2002/12/13 19:45:49 tgl Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -582,26 +582,24 @@ explain_outNode(StringInfo str,
|
||||
if (plan->initPlan)
|
||||
{
|
||||
List *saved_rtable = es->rtable;
|
||||
List *pslist = planstate->initPlan;
|
||||
List *lst;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
appendStringInfo(str, " ");
|
||||
appendStringInfo(str, " InitPlan\n");
|
||||
foreach(lst, plan->initPlan)
|
||||
foreach(lst, planstate->initPlan)
|
||||
{
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) lfirst(lst);
|
||||
SubPlanState *subplanstate = (SubPlanState *) lfirst(pslist);
|
||||
SubPlanExprState *sps = (SubPlanExprState *) lfirst(lst);
|
||||
SubPlanExpr *sp = (SubPlanExpr *) sps->xprstate.expr;
|
||||
|
||||
es->rtable = subplan->rtable;
|
||||
es->rtable = sp->rtable;
|
||||
for (i = 0; i < indent; i++)
|
||||
appendStringInfo(str, " ");
|
||||
appendStringInfo(str, " -> ");
|
||||
explain_outNode(str, subplan->plan,
|
||||
subplanstate->planstate,
|
||||
explain_outNode(str, sp->plan,
|
||||
sps->planstate,
|
||||
NULL,
|
||||
indent + 4, es);
|
||||
pslist = lnext(pslist);
|
||||
}
|
||||
es->rtable = saved_rtable;
|
||||
}
|
||||
@@ -689,8 +687,8 @@ explain_outNode(StringInfo str,
|
||||
appendStringInfo(str, " SubPlan\n");
|
||||
foreach(lst, planstate->subPlan)
|
||||
{
|
||||
SubPlanState *sps = (SubPlanState *) lfirst(lst);
|
||||
SubPlanExpr *sp = (SubPlanExpr *) sps->ps.plan;
|
||||
SubPlanExprState *sps = (SubPlanExprState *) lfirst(lst);
|
||||
SubPlanExpr *sp = (SubPlanExpr *) sps->xprstate.expr;
|
||||
|
||||
es->rtable = sp->rtable;
|
||||
for (i = 0; i < indent; i++)
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.93 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.94 2002/12/13 19:45:50 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "catalog/pg_opclass.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "executor/executor.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "optimizer/planmain.h"
|
||||
@@ -172,6 +173,8 @@ DefineIndex(RangeVar *heapRelation,
|
||||
*/
|
||||
indexInfo = makeNode(IndexInfo);
|
||||
indexInfo->ii_Predicate = cnfPred;
|
||||
indexInfo->ii_PredicateState = (List *)
|
||||
ExecInitExpr((Expr *) cnfPred, NULL);
|
||||
indexInfo->ii_FuncOid = InvalidOid;
|
||||
indexInfo->ii_Unique = unique;
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 2002, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/prepare.c,v 1.9 2002/12/05 15:50:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/prepare.c,v 1.10 2002/12/13 19:45:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "commands/prepare.h"
|
||||
#include "executor/executor.h"
|
||||
#include "utils/guc.h"
|
||||
#include "optimizer/planmain.h"
|
||||
#include "optimizer/planner.h"
|
||||
#include "rewrite/rewriteHandler.h"
|
||||
#include "tcop/pquery.h"
|
||||
@@ -110,17 +111,22 @@ ExecuteQuery(ExecuteStmt *stmt, CommandDest outputDest)
|
||||
{
|
||||
int nargs = length(entry->argtype_list);
|
||||
int i = 0;
|
||||
List *exprstates;
|
||||
ExprContext *econtext = MakeExprContext(NULL, CurrentMemoryContext);
|
||||
|
||||
/* Parser should have caught this error, but check */
|
||||
if (nargs != length(stmt->params))
|
||||
elog(ERROR, "ExecuteQuery: wrong number of arguments");
|
||||
|
||||
fix_opfuncids((Node *) stmt->params);
|
||||
|
||||
exprstates = (List *) ExecInitExpr((Expr *) stmt->params, NULL);
|
||||
|
||||
paramLI = (ParamListInfo) palloc0((nargs + 1) * sizeof(ParamListInfoData));
|
||||
|
||||
foreach(l, stmt->params)
|
||||
foreach(l, exprstates)
|
||||
{
|
||||
Node *n = lfirst(l);
|
||||
ExprState *n = lfirst(l);
|
||||
bool isNull;
|
||||
|
||||
paramLI[i].value = ExecEvalExprSwitchContext(n,
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.59 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.60 2002/12/13 19:45:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2718,6 +2718,7 @@ AlterTableAddCheckConstraint(Relation rel, Constraint *constr)
|
||||
HeapTuple tuple;
|
||||
RangeTblEntry *rte;
|
||||
List *qual;
|
||||
List *qualstate;
|
||||
Node *expr;
|
||||
|
||||
/*
|
||||
@@ -2769,6 +2770,9 @@ AlterTableAddCheckConstraint(Relation rel, Constraint *constr)
|
||||
|
||||
qual = makeList1(expr);
|
||||
|
||||
/* build execution state for qual */
|
||||
qualstate = (List *) ExecInitExpr((Expr *) qual, NULL);
|
||||
|
||||
/* Make tuple slot to hold tuples */
|
||||
slot = MakeTupleTableSlot();
|
||||
ExecSetSlotDescriptor(slot, RelationGetDescr(rel), false);
|
||||
@@ -2783,7 +2787,7 @@ AlterTableAddCheckConstraint(Relation rel, Constraint *constr)
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
|
||||
if (!ExecQual(qual, econtext, true))
|
||||
if (!ExecQual(qualstate, econtext, true))
|
||||
{
|
||||
successful = false;
|
||||
break;
|
||||
@@ -3820,6 +3824,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||
indexInfo->ii_KeyAttrNumbers[0] = 1;
|
||||
indexInfo->ii_KeyAttrNumbers[1] = 2;
|
||||
indexInfo->ii_Predicate = NIL;
|
||||
indexInfo->ii_PredicateState = NIL;
|
||||
indexInfo->ii_FuncOid = InvalidOid;
|
||||
indexInfo->ii_Unique = true;
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.23 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.24 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@@ -1244,7 +1244,8 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
|
||||
Form_pg_type typTup;
|
||||
ExprContext *econtext;
|
||||
char *ccbin;
|
||||
Node *expr;
|
||||
Expr *expr;
|
||||
ExprState *exprstate;
|
||||
int counter = 0;
|
||||
Constraint *constr;
|
||||
|
||||
@@ -1336,10 +1337,11 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
|
||||
* Test all values stored in the attributes based on the domain
|
||||
* the constraint is being added to.
|
||||
*/
|
||||
expr = stringToNode(ccbin);
|
||||
fix_opfuncids(expr);
|
||||
expr = (Expr *) stringToNode(ccbin);
|
||||
fix_opfuncids((Node *) expr);
|
||||
exprstate = ExecInitExpr(expr, NULL);
|
||||
|
||||
/* Make an expression context for ExecQual */
|
||||
/* Make an expression context for ExecEvalExpr */
|
||||
econtext = MakeExprContext(NULL, CurrentMemoryContext);
|
||||
|
||||
rels = get_rels_with_domain(domainoid);
|
||||
@@ -1375,7 +1377,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
|
||||
econtext->domainValue_datum = d;
|
||||
econtext->domainValue_isNull = isNull;
|
||||
|
||||
conResult = ExecEvalExpr(expr, econtext, &isNull, NULL);
|
||||
conResult = ExecEvalExpr(exprstate, econtext, &isNull, NULL);
|
||||
|
||||
if (!isNull && !DatumGetBool(conResult))
|
||||
elog(ERROR, "AlterDomainAddConstraint: Domain %s constraint %s failed",
|
||||
|
@@ -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/executor/execAmi.c,v 1.66 2002/12/05 15:50:30 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.67 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -61,17 +61,19 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
|
||||
|
||||
foreach(lst, node->initPlan)
|
||||
{
|
||||
PlanState *splan = ((SubPlanState *) lfirst(lst))->planstate;
|
||||
SubPlanExprState *sstate = (SubPlanExprState *) lfirst(lst);
|
||||
PlanState *splan = sstate->planstate;
|
||||
|
||||
if (splan->plan->extParam != NIL) /* don't care about child
|
||||
* locParam */
|
||||
SetChangedParamList(splan, node->chgParam);
|
||||
if (splan->chgParam != NIL)
|
||||
ExecReScanSetParamPlan((SubPlanState *) lfirst(lst), node);
|
||||
ExecReScanSetParamPlan(sstate, node);
|
||||
}
|
||||
foreach(lst, node->subPlan)
|
||||
{
|
||||
PlanState *splan = ((SubPlanState *) lfirst(lst))->planstate;
|
||||
SubPlanExprState *sstate = (SubPlanExprState *) lfirst(lst);
|
||||
PlanState *splan = sstate->planstate;
|
||||
|
||||
if (splan->plan->extParam != NIL)
|
||||
SetChangedParamList(splan, node->chgParam);
|
||||
|
@@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.191 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.192 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1543,7 +1543,8 @@ ExecRelCheck(ResultRelInfo *resultRelInfo,
|
||||
{
|
||||
qual = (List *) stringToNode(check[i].ccbin);
|
||||
fix_opfuncids((Node *) qual);
|
||||
resultRelInfo->ri_ConstraintExprs[i] = qual;
|
||||
resultRelInfo->ri_ConstraintExprs[i] = (List *)
|
||||
ExecInitExpr((Expr *) qual, NULL);
|
||||
}
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.32 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.33 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -229,23 +229,29 @@ ExecInitNode(Plan *node, EState *estate)
|
||||
foreach(subp, node->initPlan)
|
||||
{
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) lfirst(subp);
|
||||
SubPlanExprState *sstate;
|
||||
|
||||
Assert(IsA(subplan, SubPlanExpr));
|
||||
subps = lappend(subps, ExecInitSubPlan(subplan, estate));
|
||||
sstate = ExecInitExprInitPlan(subplan, result);
|
||||
ExecInitSubPlan(sstate, estate);
|
||||
subps = lappend(subps, sstate);
|
||||
}
|
||||
result->initPlan = subps;
|
||||
|
||||
/*
|
||||
* Initialize any subPlans present in this node. These were found
|
||||
* by ExecInitExpr during initialization of the PlanState.
|
||||
* by ExecInitExpr during initialization of the PlanState. Note we
|
||||
* must do this after initializing initPlans, in case their arguments
|
||||
* contain subPlans (is that actually possible? perhaps not).
|
||||
*/
|
||||
subps = NIL;
|
||||
foreach(subp, result->subPlan)
|
||||
{
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) lfirst(subp);
|
||||
SubPlanExprState *sstate = (SubPlanExprState *) lfirst(subp);
|
||||
|
||||
Assert(IsA(subplan, SubPlanExpr));
|
||||
subps = lappend(subps, ExecInitSubPlan(subplan, estate));
|
||||
Assert(IsA(sstate, SubPlanExprState));
|
||||
ExecInitSubPlan(sstate, estate);
|
||||
subps = lappend(subps, sstate);
|
||||
}
|
||||
result->subPlan = subps;
|
||||
|
||||
@@ -492,14 +498,11 @@ ExecEndNode(PlanState *node)
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
if (node->instrument)
|
||||
InstrEndLoop(node->instrument);
|
||||
|
||||
/* Clean up initPlans and subPlans */
|
||||
foreach(subp, node->initPlan)
|
||||
ExecEndSubPlan((SubPlanState *) lfirst(subp));
|
||||
ExecEndSubPlan((SubPlanExprState *) lfirst(subp));
|
||||
foreach(subp, node->subPlan)
|
||||
ExecEndSubPlan((SubPlanState *) lfirst(subp));
|
||||
ExecEndSubPlan((SubPlanExprState *) lfirst(subp));
|
||||
|
||||
if (node->chgParam != NIL)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.62 2002/12/12 15:49:28 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.63 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -550,6 +550,7 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
|
||||
* ExecTypeFromTL
|
||||
*
|
||||
* Generate a tuple descriptor for the result tuple of a targetlist.
|
||||
* (A parse/plan tlist must be passed, not an ExprState tlist.)
|
||||
* Note that resjunk columns, if any, are included in the result.
|
||||
*
|
||||
* Currently there are about 4 different places where we create
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.91 2002/12/05 15:50:32 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.92 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -321,9 +321,9 @@ ExecAssignResultTypeFromTL(PlanState *planstate)
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Some plan nodes don't bother to set up planstate->targetlist,
|
||||
* so use the underlying plan's targetlist instead. This will probably
|
||||
* need to be fixed later.
|
||||
* ExecTypeFromTL needs the parse-time representation of the tlist, not
|
||||
* a list of ExprStates. This is good because some plan nodes don't
|
||||
* bother to set up planstate->targetlist ...
|
||||
*/
|
||||
tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
|
||||
ExecAssignResultType(planstate, tupDesc, true);
|
||||
@@ -681,7 +681,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
|
||||
continue;
|
||||
|
||||
indexInfo = indexInfoArray[i];
|
||||
predicate = indexInfo->ii_Predicate;
|
||||
predicate = indexInfo->ii_PredicateState;
|
||||
if (predicate != NIL)
|
||||
{
|
||||
/* Skip this index-update if the predicate isn't satisfied */
|
||||
|
@@ -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.99 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.100 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -82,7 +82,8 @@ typedef struct AggStatePerAggData
|
||||
* thereafter:
|
||||
*/
|
||||
|
||||
/* Link to Aggref node this working state is for */
|
||||
/* Links to Aggref expr and state nodes this working state is for */
|
||||
AggrefExprState *aggrefstate;
|
||||
Aggref *aggref;
|
||||
|
||||
/* Oids of transfer functions */
|
||||
@@ -237,7 +238,7 @@ initialize_aggregates(AggState *aggstate,
|
||||
{
|
||||
AggStatePerAgg peraggstate = &peragg[aggno];
|
||||
AggStatePerGroup pergroupstate = &pergroup[aggno];
|
||||
Aggref *aggref = peraggstate->aggref;
|
||||
Aggref *aggref = peraggstate->aggref;
|
||||
|
||||
/*
|
||||
* Start a fresh sort operation for each DISTINCT aggregate.
|
||||
@@ -411,11 +412,12 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
|
||||
{
|
||||
AggStatePerAgg peraggstate = &aggstate->peragg[aggno];
|
||||
AggStatePerGroup pergroupstate = &pergroup[aggno];
|
||||
AggrefExprState *aggrefstate = peraggstate->aggrefstate;
|
||||
Aggref *aggref = peraggstate->aggref;
|
||||
Datum newVal;
|
||||
bool isNull;
|
||||
|
||||
newVal = ExecEvalExprSwitchContext((Node *) aggref->target, econtext,
|
||||
newVal = ExecEvalExprSwitchContext(aggrefstate->target, econtext,
|
||||
&isNull, NULL);
|
||||
|
||||
if (aggref->aggdistinct)
|
||||
@@ -1145,10 +1147,10 @@ ExecInitAgg(Agg *node, EState *estate)
|
||||
* particular order.
|
||||
*/
|
||||
aggstate->ss.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->plan.targetlist,
|
||||
(PlanState *) aggstate);
|
||||
aggstate->ss.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->plan.qual,
|
||||
ExecInitExpr((Expr *) node->plan.qual,
|
||||
(PlanState *) aggstate);
|
||||
|
||||
/*
|
||||
@@ -1227,7 +1229,8 @@ ExecInitAgg(Agg *node, EState *estate)
|
||||
aggno = -1;
|
||||
foreach(alist, aggstate->aggs)
|
||||
{
|
||||
Aggref *aggref = (Aggref *) lfirst(alist);
|
||||
AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(alist);
|
||||
Aggref *aggref = (Aggref *) aggrefstate->xprstate.expr;
|
||||
AggStatePerAgg peraggstate = &peragg[++aggno];
|
||||
HeapTuple aggTuple;
|
||||
Form_pg_aggregate aggform;
|
||||
@@ -1236,10 +1239,11 @@ ExecInitAgg(Agg *node, EState *estate)
|
||||
finalfn_oid;
|
||||
Datum textInitVal;
|
||||
|
||||
/* Mark Aggref node with its associated index in the result array */
|
||||
aggref->aggno = aggno;
|
||||
/* Mark Aggref state node with assigned index in the result array */
|
||||
aggrefstate->aggno = aggno;
|
||||
|
||||
/* Fill in the peraggstate data */
|
||||
peraggstate->aggrefstate = aggrefstate;
|
||||
peraggstate->aggref = aggref;
|
||||
|
||||
aggTuple = SearchSysCache(AGGFNOID,
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.14 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.15 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -172,10 +172,10 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
scanstate->ss.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->scan.plan.targetlist,
|
||||
(PlanState *) scanstate);
|
||||
scanstate->ss.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.qual,
|
||||
ExecInitExpr((Expr *) node->scan.plan.qual,
|
||||
(PlanState *) scanstate);
|
||||
|
||||
/*
|
||||
@@ -241,7 +241,8 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
|
||||
* Other node-specific setup
|
||||
*/
|
||||
scanstate->tuplestorestate = NULL;
|
||||
scanstate->funcexpr = rte->funcexpr;
|
||||
scanstate->funcexpr = ExecInitExpr((Expr *) rte->funcexpr,
|
||||
(PlanState *) scanstate);
|
||||
|
||||
scanstate->ss.ps.ps_TupFromTlist = false;
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* locate group boundaries.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.51 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.52 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -168,10 +168,10 @@ ExecInitGroup(Group *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
grpstate->ss.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->plan.targetlist,
|
||||
(PlanState *) grpstate);
|
||||
grpstate->ss.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->plan.qual,
|
||||
ExecInitExpr((Expr *) node->plan.qual,
|
||||
(PlanState *) grpstate);
|
||||
|
||||
/*
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.69 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.70 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -76,7 +76,7 @@ ExecHash(HashState *node)
|
||||
/*
|
||||
* set expression context
|
||||
*/
|
||||
hashkeys = ((Hash *) node->ps.plan)->hashkeys;
|
||||
hashkeys = node->hashkeys;
|
||||
econtext = node->ps.ps_ExprContext;
|
||||
|
||||
/*
|
||||
@@ -138,10 +138,10 @@ ExecInitHash(Hash *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
hashstate->ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->plan.targetlist,
|
||||
(PlanState *) hashstate);
|
||||
hashstate->ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->plan.qual,
|
||||
ExecInitExpr((Expr *) node->plan.qual,
|
||||
(PlanState *) hashstate);
|
||||
|
||||
/*
|
||||
@@ -554,7 +554,8 @@ ExecHashGetBucket(HashJoinTable hashtable,
|
||||
/*
|
||||
* Get the join attribute value of the tuple
|
||||
*/
|
||||
keyval = ExecEvalExpr(lfirst(hk), econtext, &isNull, NULL);
|
||||
keyval = ExecEvalExpr((ExprState *) lfirst(hk),
|
||||
econtext, &isNull, NULL);
|
||||
|
||||
/*
|
||||
* Compute the hash function
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.43 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.44 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -169,7 +169,7 @@ ExecHashJoin(HashJoinState *node)
|
||||
* for this tuple from the hash table
|
||||
*/
|
||||
node->hj_CurBucketNo = ExecHashGetBucket(hashtable, econtext,
|
||||
outerkeys);
|
||||
outerkeys);
|
||||
node->hj_CurTuple = NULL;
|
||||
|
||||
/*
|
||||
@@ -302,6 +302,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
|
||||
HashJoinState *hjstate;
|
||||
Plan *outerNode;
|
||||
Hash *hashNode;
|
||||
List *hclauses;
|
||||
List *hcl;
|
||||
|
||||
/*
|
||||
@@ -322,17 +323,17 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
hjstate->js.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->join.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->join.plan.targetlist,
|
||||
(PlanState *) hjstate);
|
||||
hjstate->js.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->join.plan.qual,
|
||||
ExecInitExpr((Expr *) node->join.plan.qual,
|
||||
(PlanState *) hjstate);
|
||||
hjstate->js.jointype = node->join.jointype;
|
||||
hjstate->js.joinqual = (List *)
|
||||
ExecInitExpr((Node *) node->join.joinqual,
|
||||
ExecInitExpr((Expr *) node->join.joinqual,
|
||||
(PlanState *) hjstate);
|
||||
hjstate->hashclauses = (List *)
|
||||
ExecInitExpr((Node *) node->hashclauses,
|
||||
ExecInitExpr((Expr *) node->hashclauses,
|
||||
(PlanState *) hjstate);
|
||||
|
||||
/*
|
||||
@@ -402,15 +403,23 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
|
||||
|
||||
/*
|
||||
* The planner already made a list of the inner hashkeys for us,
|
||||
* but we also need a list of the outer hashkeys.
|
||||
* but we also need a list of the outer hashkeys. Each list of
|
||||
* exprs must then be prepared for execution.
|
||||
*/
|
||||
hjstate->hj_InnerHashKeys = hashNode->hashkeys;
|
||||
hjstate->hj_OuterHashKeys = NIL;
|
||||
hjstate->hj_InnerHashKeys = (List *)
|
||||
ExecInitExpr((Expr *) hashNode->hashkeys,
|
||||
innerPlanState(hjstate));
|
||||
((HashState *) innerPlanState(hjstate))->hashkeys =
|
||||
hjstate->hj_InnerHashKeys;
|
||||
|
||||
hclauses = NIL;
|
||||
foreach(hcl, node->hashclauses)
|
||||
{
|
||||
hjstate->hj_OuterHashKeys = lappend(hjstate->hj_OuterHashKeys,
|
||||
get_leftop(lfirst(hcl)));
|
||||
hclauses = lappend(hclauses, get_leftop(lfirst(hcl)));
|
||||
}
|
||||
hjstate->hj_OuterHashKeys = (List *)
|
||||
ExecInitExpr((Expr *) hclauses,
|
||||
(PlanState *) hjstate);
|
||||
|
||||
hjstate->js.ps.ps_OuterTupleSlot = NULL;
|
||||
hjstate->js.ps.ps_TupFromTlist = false;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.73 2002/12/12 15:49:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.74 2002/12/13 19:45:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -283,7 +283,7 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt)
|
||||
int numIndices;
|
||||
IndexScanDescPtr scanDescs;
|
||||
ScanKey *scanKeys;
|
||||
int **runtimeKeyInfo;
|
||||
ExprState ***runtimeKeyInfo;
|
||||
int *numScanKeys;
|
||||
Index scanrelid;
|
||||
int i;
|
||||
@@ -328,29 +328,18 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt)
|
||||
*/
|
||||
if (runtimeKeyInfo)
|
||||
{
|
||||
List *indxqual;
|
||||
|
||||
indxqual = node->indxqual;
|
||||
for (i = 0; i < numIndices; i++)
|
||||
{
|
||||
List *qual = lfirst(indxqual);
|
||||
int n_keys;
|
||||
ScanKey scan_keys;
|
||||
int *run_keys;
|
||||
List *listscan;
|
||||
ExprState **run_keys;
|
||||
|
||||
indxqual = lnext(indxqual);
|
||||
n_keys = numScanKeys[i];
|
||||
scan_keys = scanKeys[i];
|
||||
run_keys = runtimeKeyInfo[i];
|
||||
|
||||
listscan = qual;
|
||||
for (j = 0; j < n_keys; j++)
|
||||
{
|
||||
Expr *clause = lfirst(listscan);
|
||||
|
||||
listscan = lnext(listscan);
|
||||
|
||||
/*
|
||||
* If we have a run-time key, then extract the run-time
|
||||
* expression and evaluate it with respect to the current
|
||||
@@ -364,17 +353,12 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt)
|
||||
* is wrong, we could copy the result into our context
|
||||
* explicitly, but I think that's not necessary...
|
||||
*/
|
||||
if (run_keys[j] != NO_OP)
|
||||
if (run_keys[j] != NULL)
|
||||
{
|
||||
Node *scanexpr;
|
||||
Datum scanvalue;
|
||||
bool isNull;
|
||||
|
||||
scanexpr = (run_keys[j] == RIGHT_OP) ?
|
||||
(Node *) get_rightop(clause) :
|
||||
(Node *) get_leftop(clause);
|
||||
|
||||
scanvalue = ExecEvalExprSwitchContext(scanexpr,
|
||||
scanvalue = ExecEvalExprSwitchContext(run_keys[j],
|
||||
econtext,
|
||||
&isNull,
|
||||
NULL);
|
||||
@@ -424,7 +408,7 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt)
|
||||
void
|
||||
ExecEndIndexScan(IndexScanState *node)
|
||||
{
|
||||
int **runtimeKeyInfo;
|
||||
ExprState ***runtimeKeyInfo;
|
||||
ScanKey *scanKeys;
|
||||
int *numScanKeys;
|
||||
int numIndices;
|
||||
@@ -585,7 +569,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
int *numScanKeys;
|
||||
RelationPtr indexDescs;
|
||||
IndexScanDescPtr scanDescs;
|
||||
int **runtimeKeyInfo;
|
||||
ExprState ***runtimeKeyInfo;
|
||||
bool have_runtime_keys;
|
||||
RangeTblEntry *rtentry;
|
||||
Index relid;
|
||||
@@ -610,16 +594,16 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
indexstate->ss.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->scan.plan.targetlist,
|
||||
(PlanState *) indexstate);
|
||||
indexstate->ss.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.qual,
|
||||
ExecInitExpr((Expr *) node->scan.plan.qual,
|
||||
(PlanState *) indexstate);
|
||||
indexstate->indxqual = (List *)
|
||||
ExecInitExpr((Node *) node->indxqual,
|
||||
ExecInitExpr((Expr *) node->indxqual,
|
||||
(PlanState *) indexstate);
|
||||
indexstate->indxqualorig = (List *)
|
||||
ExecInitExpr((Node *) node->indxqualorig,
|
||||
ExecInitExpr((Expr *) node->indxqualorig,
|
||||
(PlanState *) indexstate);
|
||||
|
||||
#define INDEXSCAN_NSLOTS 2
|
||||
@@ -672,7 +656,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
* initialize space for runtime key info (may not be needed)
|
||||
*/
|
||||
have_runtime_keys = false;
|
||||
runtimeKeyInfo = (int **) palloc(numIndices * sizeof(int *));
|
||||
runtimeKeyInfo = (ExprState ***) palloc0(numIndices * sizeof(ExprState **));
|
||||
|
||||
/*
|
||||
* build the index scan keys from the index qualification
|
||||
@@ -684,15 +668,15 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
List *qual;
|
||||
int n_keys;
|
||||
ScanKey scan_keys;
|
||||
int *run_keys;
|
||||
ExprState **run_keys;
|
||||
|
||||
qual = lfirst(indxqual);
|
||||
indxqual = lnext(indxqual);
|
||||
n_keys = length(qual);
|
||||
scan_keys = (n_keys <= 0) ? (ScanKey) NULL :
|
||||
(ScanKey) palloc(n_keys * sizeof(ScanKeyData));
|
||||
run_keys = (n_keys <= 0) ? (int *) NULL :
|
||||
(int *) palloc(n_keys * sizeof(int));
|
||||
run_keys = (n_keys <= 0) ? (ExprState **) NULL :
|
||||
(ExprState **) palloc(n_keys * sizeof(ExprState *));
|
||||
|
||||
CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext);
|
||||
|
||||
@@ -704,8 +688,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
for (j = 0; j < n_keys; j++)
|
||||
{
|
||||
OpExpr *clause; /* one clause of index qual */
|
||||
Node *leftop; /* expr on lhs of operator */
|
||||
Node *rightop; /* expr on rhs ... */
|
||||
Expr *leftop; /* expr on lhs of operator */
|
||||
Expr *rightop; /* expr on rhs ... */
|
||||
bits16 flags = 0;
|
||||
|
||||
int scanvar; /* which var identifies varattno */
|
||||
@@ -740,9 +724,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
* which case we need to recalculate the index scan key at run
|
||||
* time.
|
||||
*
|
||||
* Hence, we set have_runtime_keys to true and then set the
|
||||
* appropriate flag in run_keys to LEFT_OP or RIGHT_OP. The
|
||||
* corresponding scan keys are recomputed at run time.
|
||||
* Hence, we set have_runtime_keys to true and place the
|
||||
* appropriate subexpression in run_keys. The corresponding
|
||||
* scan key values are recomputed at run time.
|
||||
*
|
||||
* XXX Although this code *thinks* it can handle an indexqual
|
||||
* with the indexkey on either side, in fact it cannot.
|
||||
@@ -760,19 +744,20 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
*/
|
||||
|
||||
scanvar = NO_OP;
|
||||
run_keys[j] = NO_OP;
|
||||
run_keys[j] = NULL;
|
||||
|
||||
/*
|
||||
* determine information in leftop
|
||||
*/
|
||||
leftop = (Node *) get_leftop((Expr *) clause);
|
||||
leftop = (Expr *) get_leftop((Expr *) clause);
|
||||
|
||||
if (leftop && IsA(leftop, RelabelType))
|
||||
leftop = (Node *) ((RelabelType *) leftop)->arg;
|
||||
leftop = ((RelabelType *) leftop)->arg;
|
||||
|
||||
Assert(leftop != NULL);
|
||||
|
||||
if (IsA(leftop, Var) &&var_is_rel((Var *) leftop))
|
||||
if (IsA(leftop, Var) &&
|
||||
var_is_rel((Var *) leftop))
|
||||
{
|
||||
/*
|
||||
* if the leftop is a "rel-var", then it means that it is
|
||||
@@ -792,32 +777,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
if (((Const *) leftop)->constisnull)
|
||||
flags |= SK_ISNULL;
|
||||
}
|
||||
else if (IsA(leftop, Param))
|
||||
{
|
||||
bool isnull;
|
||||
|
||||
/*
|
||||
* if the leftop is a Param node then it means it
|
||||
* identifies the value to place in our scan key.
|
||||
*/
|
||||
|
||||
/* Life was so easy before ... subselects */
|
||||
if (((Param *) leftop)->paramkind == PARAM_EXEC)
|
||||
{
|
||||
/* treat Param as runtime key */
|
||||
have_runtime_keys = true;
|
||||
run_keys[j] = LEFT_OP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* treat Param like a constant */
|
||||
scanvalue = ExecEvalParam((Param *) leftop,
|
||||
indexstate->ss.ps.ps_ExprContext,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
flags |= SK_ISNULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -826,20 +785,21 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
* key.
|
||||
*/
|
||||
have_runtime_keys = true;
|
||||
run_keys[j] = LEFT_OP;
|
||||
run_keys[j] = ExecInitExpr(leftop, (PlanState *) indexstate);
|
||||
}
|
||||
|
||||
/*
|
||||
* now determine information in rightop
|
||||
*/
|
||||
rightop = (Node *) get_rightop((Expr *) clause);
|
||||
rightop = (Expr *) get_rightop((Expr *) clause);
|
||||
|
||||
if (rightop && IsA(rightop, RelabelType))
|
||||
rightop = (Node *) ((RelabelType *) rightop)->arg;
|
||||
rightop = ((RelabelType *) rightop)->arg;
|
||||
|
||||
Assert(rightop != NULL);
|
||||
|
||||
if (IsA(rightop, Var) &&var_is_rel((Var *) rightop))
|
||||
if (IsA(rightop, Var) &&
|
||||
var_is_rel((Var *) rightop))
|
||||
{
|
||||
/*
|
||||
* here we make sure only one op identifies the
|
||||
@@ -867,32 +827,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
if (((Const *) rightop)->constisnull)
|
||||
flags |= SK_ISNULL;
|
||||
}
|
||||
else if (IsA(rightop, Param))
|
||||
{
|
||||
bool isnull;
|
||||
|
||||
/*
|
||||
* if the rightop is a Param node then it means it
|
||||
* identifies the value to place in our scan key.
|
||||
*/
|
||||
|
||||
/* Life was so easy before ... subselects */
|
||||
if (((Param *) rightop)->paramkind == PARAM_EXEC)
|
||||
{
|
||||
/* treat Param as runtime key */
|
||||
have_runtime_keys = true;
|
||||
run_keys[j] = RIGHT_OP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* treat Param like a constant */
|
||||
scanvalue = ExecEvalParam((Param *) rightop,
|
||||
indexstate->ss.ps.ps_ExprContext,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
flags |= SK_ISNULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
@@ -901,7 +835,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
|
||||
* key.
|
||||
*/
|
||||
have_runtime_keys = true;
|
||||
run_keys[j] = RIGHT_OP;
|
||||
run_keys[j] = ExecInitExpr(rightop, (PlanState *) indexstate);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeLimit.c,v 1.12 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeLimit.c,v 1.13 2002/12/13 19:45:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -301,9 +301,9 @@ ExecInitLimit(Limit *node, EState *estate)
|
||||
/*
|
||||
* initialize child expressions
|
||||
*/
|
||||
limitstate->limitOffset = ExecInitExpr(node->limitOffset,
|
||||
limitstate->limitOffset = ExecInitExpr((Expr *) node->limitOffset,
|
||||
(PlanState *) limitstate);
|
||||
limitstate->limitCount = ExecInitExpr(node->limitCount,
|
||||
limitstate->limitCount = ExecInitExpr((Expr *) node->limitCount,
|
||||
(PlanState *) limitstate);
|
||||
|
||||
#define LIMIT_NSLOTS 1
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.53 2002/12/12 15:49:25 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.54 2002/12/13 19:45:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -101,23 +101,26 @@ static bool MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals)
|
||||
MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals,
|
||||
PlanState *parent)
|
||||
{
|
||||
List *ltcdr,
|
||||
List *ltexprs,
|
||||
*gtexprs,
|
||||
*ltcdr,
|
||||
*gtcdr;
|
||||
|
||||
/*
|
||||
* Make modifiable copies of the qualList.
|
||||
*/
|
||||
*ltQuals = (List *) copyObject((Node *) qualList);
|
||||
*gtQuals = (List *) copyObject((Node *) qualList);
|
||||
ltexprs = (List *) copyObject((Node *) qualList);
|
||||
gtexprs = (List *) copyObject((Node *) qualList);
|
||||
|
||||
/*
|
||||
* Scan both lists in parallel, so that we can update the operators
|
||||
* with the minimum number of syscache searches.
|
||||
*/
|
||||
ltcdr = *ltQuals;
|
||||
foreach(gtcdr, *gtQuals)
|
||||
ltcdr = ltexprs;
|
||||
foreach(gtcdr, gtexprs)
|
||||
{
|
||||
OpExpr *ltop = (OpExpr *) lfirst(ltcdr);
|
||||
OpExpr *gtop = (OpExpr *) lfirst(gtcdr);
|
||||
@@ -137,11 +140,15 @@ MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals)
|
||||
>op->opno,
|
||||
<op->opfuncid,
|
||||
>op->opfuncid);
|
||||
ltop->op_fcache = NULL;
|
||||
gtop->op_fcache = NULL;
|
||||
|
||||
ltcdr = lnext(ltcdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare both lists for execution.
|
||||
*/
|
||||
*ltQuals = (List *) ExecInitExpr((Expr *) ltexprs, parent);
|
||||
*gtQuals = (List *) ExecInitExpr((Expr *) gtexprs, parent);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@@ -193,8 +200,10 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
|
||||
*
|
||||
* A NULL result is considered false.
|
||||
*/
|
||||
const_value = ExecEvalExpr((Node *) lfirst(clause), econtext,
|
||||
&isNull, NULL);
|
||||
const_value = ExecEvalExpr((ExprState *) lfirst(clause),
|
||||
econtext,
|
||||
&isNull,
|
||||
NULL);
|
||||
|
||||
if (DatumGetBool(const_value) && !isNull)
|
||||
{
|
||||
@@ -208,7 +217,7 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
|
||||
* key1 = key2 so we move on to the next pair of keys.
|
||||
*-----------
|
||||
*/
|
||||
const_value = ExecEvalExpr((Node *) lfirst(eqclause),
|
||||
const_value = ExecEvalExpr((ExprState *) lfirst(eqclause),
|
||||
econtext,
|
||||
&isNull,
|
||||
NULL);
|
||||
@@ -1409,17 +1418,17 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
mergestate->js.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->join.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->join.plan.targetlist,
|
||||
(PlanState *) mergestate);
|
||||
mergestate->js.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->join.plan.qual,
|
||||
ExecInitExpr((Expr *) node->join.plan.qual,
|
||||
(PlanState *) mergestate);
|
||||
mergestate->js.jointype = node->join.jointype;
|
||||
mergestate->js.joinqual = (List *)
|
||||
ExecInitExpr((Node *) node->join.joinqual,
|
||||
ExecInitExpr((Expr *) node->join.joinqual,
|
||||
(PlanState *) mergestate);
|
||||
mergestate->mergeclauses = (List *)
|
||||
ExecInitExpr((Node *) node->mergeclauses,
|
||||
ExecInitExpr((Expr *) node->mergeclauses,
|
||||
(PlanState *) mergestate);
|
||||
|
||||
/*
|
||||
@@ -1492,7 +1501,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
|
||||
*/
|
||||
MJFormSkipQuals(node->mergeclauses,
|
||||
&mergestate->mj_OuterSkipQual,
|
||||
&mergestate->mj_InnerSkipQual);
|
||||
&mergestate->mj_InnerSkipQual,
|
||||
(PlanState *) mergestate);
|
||||
|
||||
MJ_printf("\nExecInitMergeJoin: OuterSkipQual is ");
|
||||
MJ_nodeDisplay(mergestate->mj_OuterSkipQual);
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.27 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.28 2002/12/13 19:45:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -286,14 +286,14 @@ ExecInitNestLoop(NestLoop *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
nlstate->js.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->join.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->join.plan.targetlist,
|
||||
(PlanState *) nlstate);
|
||||
nlstate->js.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->join.plan.qual,
|
||||
ExecInitExpr((Expr *) node->join.plan.qual,
|
||||
(PlanState *) nlstate);
|
||||
nlstate->js.jointype = node->join.jointype;
|
||||
nlstate->js.joinqual = (List *)
|
||||
ExecInitExpr((Node *) node->join.joinqual,
|
||||
ExecInitExpr((Expr *) node->join.joinqual,
|
||||
(PlanState *) nlstate);
|
||||
|
||||
/*
|
||||
|
@@ -34,7 +34,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.22 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.23 2002/12/13 19:45:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -205,12 +205,12 @@ ExecInitResult(Result *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
resstate->ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->plan.targetlist,
|
||||
(PlanState *) resstate);
|
||||
resstate->ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->plan.qual,
|
||||
ExecInitExpr((Expr *) node->plan.qual,
|
||||
(PlanState *) resstate);
|
||||
resstate->resconstantqual = ExecInitExpr(node->resconstantqual,
|
||||
resstate->resconstantqual = ExecInitExpr((Expr *) node->resconstantqual,
|
||||
(PlanState *) resstate);
|
||||
|
||||
/*
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.39 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.40 2002/12/13 19:45:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -207,10 +207,10 @@ ExecInitSeqScan(SeqScan *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
scanstate->ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->plan.targetlist,
|
||||
(PlanState *) scanstate);
|
||||
scanstate->ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->plan.qual,
|
||||
ExecInitExpr((Expr *) node->plan.qual,
|
||||
(PlanState *) scanstate);
|
||||
|
||||
#define SEQSCAN_NSLOTS 2
|
||||
|
@@ -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.36 2002/12/12 15:49:27 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.37 2002/12/13 19:45:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -30,11 +30,12 @@
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
Datum
|
||||
ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
ExprContext *econtext, bool *isNull)
|
||||
ExecSubPlan(SubPlanExprState *node,
|
||||
ExprContext *econtext,
|
||||
bool *isNull)
|
||||
{
|
||||
PlanState *planstate = node->planstate;
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) node->ps.plan;
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) node->xprstate.expr;
|
||||
SubLink *sublink = subplan->sublink;
|
||||
SubLinkType subLinkType = sublink->subLinkType;
|
||||
bool useor = sublink->useor;
|
||||
@@ -42,6 +43,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
TupleTableSlot *slot;
|
||||
Datum result;
|
||||
bool found = false; /* TRUE if got at least one subplan tuple */
|
||||
List *pvar;
|
||||
List *lst;
|
||||
|
||||
/*
|
||||
@@ -56,6 +58,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
/*
|
||||
* Set Params of this plan from parent plan correlation Vars
|
||||
*/
|
||||
pvar = node->args;
|
||||
if (subplan->parParam != NIL)
|
||||
{
|
||||
foreach(lst, subplan->parParam)
|
||||
@@ -64,7 +67,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
|
||||
prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
|
||||
Assert(pvar != NIL);
|
||||
prm->value = ExecEvalExprSwitchContext((Node *) lfirst(pvar),
|
||||
prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
|
||||
econtext,
|
||||
&(prm->isnull),
|
||||
NULL);
|
||||
@@ -149,9 +152,10 @@ ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
* For ALL, ANY, and MULTIEXPR sublinks, iterate over combining
|
||||
* operators for columns of tuple.
|
||||
*/
|
||||
foreach(lst, sublink->oper)
|
||||
foreach(lst, node->oper)
|
||||
{
|
||||
OpExpr *expr = (OpExpr *) lfirst(lst);
|
||||
ExprState *exprstate = (ExprState *) lfirst(lst);
|
||||
OpExpr *expr = (OpExpr *) exprstate->expr;
|
||||
Param *prm = lsecond(expr->args);
|
||||
ParamExecData *prmdata;
|
||||
Datum expresult;
|
||||
@@ -194,7 +198,7 @@ ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
/*
|
||||
* Now we can eval the combining operator for this column.
|
||||
*/
|
||||
expresult = ExecEvalExprSwitchContext((Node *) expr, econtext,
|
||||
expresult = ExecEvalExprSwitchContext(exprstate, econtext,
|
||||
&expnull, NULL);
|
||||
|
||||
/*
|
||||
@@ -287,64 +291,57 @@ ExecSubPlan(SubPlanState *node, List *pvar,
|
||||
* ExecInitSubPlan
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
SubPlanState *
|
||||
ExecInitSubPlan(SubPlanExpr *node, EState *estate)
|
||||
void
|
||||
ExecInitSubPlan(SubPlanExprState *sstate, EState *estate)
|
||||
{
|
||||
SubPlanState *subplanstate;
|
||||
SubPlanExpr *expr = (SubPlanExpr *) sstate->xprstate.expr;
|
||||
EState *sp_estate;
|
||||
|
||||
/*
|
||||
* Do access checking on the rangetable entries in the subquery.
|
||||
* Here, we assume the subquery is a SELECT.
|
||||
*/
|
||||
ExecCheckRTPerms(node->rtable, CMD_SELECT);
|
||||
ExecCheckRTPerms(expr->rtable, CMD_SELECT);
|
||||
|
||||
/*
|
||||
* create state structure
|
||||
* initialize state
|
||||
*/
|
||||
subplanstate = makeNode(SubPlanState);
|
||||
subplanstate->ps.plan = (Plan *) node;
|
||||
subplanstate->ps.state = estate;
|
||||
|
||||
subplanstate->needShutdown = false;
|
||||
subplanstate->curTuple = NULL;
|
||||
|
||||
/* XXX temporary hack */
|
||||
node->pstate = subplanstate;
|
||||
sstate->needShutdown = false;
|
||||
sstate->curTuple = NULL;
|
||||
|
||||
/*
|
||||
* create an EState for the subplan
|
||||
*/
|
||||
sp_estate = CreateExecutorState();
|
||||
|
||||
sp_estate->es_range_table = node->rtable;
|
||||
sp_estate->es_range_table = expr->rtable;
|
||||
sp_estate->es_param_list_info = estate->es_param_list_info;
|
||||
sp_estate->es_param_exec_vals = estate->es_param_exec_vals;
|
||||
sp_estate->es_tupleTable =
|
||||
ExecCreateTupleTable(ExecCountSlotsNode(node->plan) + 10);
|
||||
ExecCreateTupleTable(ExecCountSlotsNode(expr->plan) + 10);
|
||||
sp_estate->es_snapshot = estate->es_snapshot;
|
||||
sp_estate->es_instrument = estate->es_instrument;
|
||||
|
||||
/*
|
||||
* Start up the subplan
|
||||
*/
|
||||
subplanstate->planstate = ExecInitNode(node->plan, sp_estate);
|
||||
sstate->planstate = ExecInitNode(expr->plan, sp_estate);
|
||||
|
||||
subplanstate->needShutdown = true; /* now we need to shutdown the subplan */
|
||||
sstate->needShutdown = true; /* now we need to shutdown the subplan */
|
||||
|
||||
/*
|
||||
* If this plan is un-correlated or undirect correlated one and want
|
||||
* to set params for parent plan then prepare parameters.
|
||||
*/
|
||||
if (node->setParam != NIL)
|
||||
if (expr->setParam != NIL)
|
||||
{
|
||||
List *lst;
|
||||
|
||||
foreach(lst, node->setParam)
|
||||
foreach(lst, expr->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = subplanstate;
|
||||
prm->execPlan = sstate;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -353,8 +350,6 @@ ExecInitSubPlan(SubPlanExpr *node, EState *estate)
|
||||
* it, for others - it doesn't matter...
|
||||
*/
|
||||
}
|
||||
|
||||
return subplanstate;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@@ -371,12 +366,11 @@ ExecInitSubPlan(SubPlanExpr *node, EState *estate)
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
ExecSetParamPlan(SubPlanExprState *node, ExprContext *econtext)
|
||||
{
|
||||
PlanState *planstate = node->planstate;
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) node->ps.plan;
|
||||
SubLink *sublink = subplan->sublink;
|
||||
EState *estate = node->ps.state;
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) node->xprstate.expr;
|
||||
SubLinkType subLinkType = subplan->sublink->subLinkType;
|
||||
MemoryContext oldcontext;
|
||||
TupleTableSlot *slot;
|
||||
List *lst;
|
||||
@@ -388,8 +382,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
*/
|
||||
oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
|
||||
|
||||
if (sublink->subLinkType == ANY_SUBLINK ||
|
||||
sublink->subLinkType == ALL_SUBLINK)
|
||||
if (subLinkType == ANY_SUBLINK ||
|
||||
subLinkType == ALL_SUBLINK)
|
||||
elog(ERROR, "ExecSetParamPlan: ANY/ALL subselect unsupported");
|
||||
|
||||
if (planstate->chgParam != NULL)
|
||||
@@ -403,9 +397,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
TupleDesc tdesc = slot->ttc_tupleDescriptor;
|
||||
int i = 1;
|
||||
|
||||
if (sublink->subLinkType == EXISTS_SUBLINK)
|
||||
if (subLinkType == EXISTS_SUBLINK)
|
||||
{
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(subplan->setParam)]);
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(subplan->setParam)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = BoolGetDatum(true);
|
||||
@@ -415,8 +409,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
}
|
||||
|
||||
if (found &&
|
||||
(sublink->subLinkType == EXPR_SUBLINK ||
|
||||
sublink->subLinkType == MULTIEXPR_SUBLINK))
|
||||
(subLinkType == EXPR_SUBLINK ||
|
||||
subLinkType == MULTIEXPR_SUBLINK))
|
||||
elog(ERROR, "More than one tuple returned by a subselect used as an expression.");
|
||||
|
||||
found = true;
|
||||
@@ -434,7 +428,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
|
||||
foreach(lst, subplan->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = heap_getattr(tup, i, tdesc, &(prm->isnull));
|
||||
@@ -444,9 +438,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (sublink->subLinkType == EXISTS_SUBLINK)
|
||||
if (subLinkType == EXISTS_SUBLINK)
|
||||
{
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(subplan->setParam)]);
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(subplan->setParam)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = BoolGetDatum(false);
|
||||
@@ -456,7 +450,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
{
|
||||
foreach(lst, subplan->setParam)
|
||||
{
|
||||
ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
|
||||
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
|
||||
|
||||
prm->execPlan = NULL;
|
||||
prm->value = (Datum) 0;
|
||||
@@ -479,7 +473,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
ExecEndSubPlan(SubPlanState *node)
|
||||
ExecEndSubPlan(SubPlanExprState *node)
|
||||
{
|
||||
if (node->needShutdown)
|
||||
{
|
||||
@@ -494,11 +488,11 @@ ExecEndSubPlan(SubPlanState *node)
|
||||
}
|
||||
|
||||
void
|
||||
ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
|
||||
ExecReScanSetParamPlan(SubPlanExprState *node, PlanState *parent)
|
||||
{
|
||||
PlanState *planstate = node->planstate;
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) node->ps.plan;
|
||||
EState *estate = node->ps.state;
|
||||
SubPlanExpr *subplan = (SubPlanExpr *) node->xprstate.expr;
|
||||
EState *estate = parent->state;
|
||||
List *lst;
|
||||
|
||||
if (subplan->parParam != NULL)
|
||||
@@ -509,8 +503,7 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
|
||||
elog(ERROR, "ExecReScanSetParamPlan: extParam list of plan is NULL");
|
||||
|
||||
/*
|
||||
* Don't actual re-scan: ExecSetParamPlan does re-scan if
|
||||
* subplan->plan->chgParam is not NULL... ExecReScan (planstate, NULL);
|
||||
* Don't actually re-scan: ExecSetParamPlan does it if needed.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.14 2002/12/05 15:50:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.15 2002/12/13 19:45:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -131,10 +131,10 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
subquerystate->ss.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->scan.plan.targetlist,
|
||||
(PlanState *) subquerystate);
|
||||
subquerystate->ss.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.qual,
|
||||
ExecInitExpr((Expr *) node->scan.plan.qual,
|
||||
(PlanState *) subquerystate);
|
||||
|
||||
#define SUBQUERYSCAN_NSLOTS 1
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.28 2002/12/05 15:50:34 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.29 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -380,10 +380,10 @@ ExecInitTidScan(TidScan *node, EState *estate)
|
||||
* initialize child expressions
|
||||
*/
|
||||
tidstate->ss.ps.targetlist = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.targetlist,
|
||||
ExecInitExpr((Expr *) node->scan.plan.targetlist,
|
||||
(PlanState *) tidstate);
|
||||
tidstate->ss.ps.qual = (List *)
|
||||
ExecInitExpr((Node *) node->scan.plan.qual,
|
||||
ExecInitExpr((Expr *) node->scan.plan.qual,
|
||||
(PlanState *) tidstate);
|
||||
|
||||
#define TIDSCAN_NSLOTS 2
|
||||
@@ -404,7 +404,10 @@ ExecInitTidScan(TidScan *node, EState *estate)
|
||||
* get the tid node information
|
||||
*/
|
||||
tidList = (ItemPointerData *) palloc(length(node->tideval) * sizeof(ItemPointerData));
|
||||
numTids = TidListCreate(node->tideval,
|
||||
tidstate->tss_tideval = (List *)
|
||||
ExecInitExpr((Expr *) node->tideval,
|
||||
(PlanState *) tidstate);
|
||||
numTids = TidListCreate(tidstate->tss_tideval,
|
||||
tidstate->ss.ps.ps_ExprContext,
|
||||
tidList);
|
||||
tidPtr = -1;
|
||||
|
@@ -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.231 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.232 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -710,7 +710,6 @@ _copyAggref(Aggref *from)
|
||||
COPY_NODE_FIELD(target);
|
||||
COPY_SCALAR_FIELD(aggstar);
|
||||
COPY_SCALAR_FIELD(aggdistinct);
|
||||
COPY_SCALAR_FIELD(aggno); /* will go away soon */
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@@ -750,9 +749,6 @@ _copyFuncExpr(FuncExpr *from)
|
||||
COPY_SCALAR_FIELD(funcformat);
|
||||
COPY_NODE_FIELD(args);
|
||||
|
||||
/* Do not copy the run-time state, if any */
|
||||
newnode->func_fcache = NULL;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
@@ -770,9 +766,6 @@ _copyOpExpr(OpExpr *from)
|
||||
COPY_SCALAR_FIELD(opretset);
|
||||
COPY_NODE_FIELD(args);
|
||||
|
||||
/* Do not copy the run-time state, if any */
|
||||
newnode->op_fcache = NULL;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
@@ -790,9 +783,6 @@ _copyDistinctExpr(DistinctExpr *from)
|
||||
COPY_SCALAR_FIELD(opretset);
|
||||
COPY_NODE_FIELD(args);
|
||||
|
||||
/* Do not copy the run-time state, if any */
|
||||
newnode->op_fcache = NULL;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.20 2002/12/12 15:49:28 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.21 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -88,5 +88,4 @@ set_opfuncid(OpExpr *opexpr)
|
||||
{
|
||||
if (opexpr->opfuncid == InvalidOid)
|
||||
opexpr->opfuncid = get_opcode(opexpr->opno);
|
||||
opexpr->op_fcache = NULL; /* XXX will go away soon */
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.188 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.189 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every node type that can appear in stored rules' parsetrees *must*
|
||||
@@ -214,8 +214,6 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
|
||||
|
||||
/*
|
||||
* print the basic stuff of all nodes that inherit from Plan
|
||||
*
|
||||
* NOTE: we deliberately omit the execution state (EState)
|
||||
*/
|
||||
static void
|
||||
_outPlanInfo(StringInfo str, Plan *node)
|
||||
|
@@ -8,12 +8,13 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.142 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.143 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Path and Plan nodes do not have any readfuncs support, because we
|
||||
* never have occasion to read them in. (There was once code here that
|
||||
* claimed to read them, but it was broken as well as unused.)
|
||||
* claimed to read them, but it was broken as well as unused.) We
|
||||
* never read executor state trees, either.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -439,8 +440,6 @@ _readFuncExpr(void)
|
||||
READ_ENUM_FIELD(funcformat, CoercionForm);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
local_node->func_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
@@ -468,8 +467,6 @@ _readOpExpr(void)
|
||||
READ_BOOL_FIELD(opretset);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
local_node->op_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
@@ -497,8 +494,6 @@ _readDistinctExpr(void)
|
||||
READ_BOOL_FIELD(opretset);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
local_node->op_fcache = NULL;
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.127 2002/12/12 15:49:28 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.128 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1124,6 +1124,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
clause_strategy,
|
||||
test_strategy;
|
||||
Expr *test_expr;
|
||||
ExprState *test_exprstate;
|
||||
Datum test_result;
|
||||
bool isNull;
|
||||
Relation relation;
|
||||
@@ -1274,9 +1275,10 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
(Expr *) clause_const,
|
||||
(Expr *) pred_const);
|
||||
set_opfuncid((OpExpr *) test_expr);
|
||||
test_exprstate = ExecInitExpr(test_expr, NULL);
|
||||
|
||||
econtext = MakeExprContext(NULL, TransactionCommandContext);
|
||||
test_result = ExecEvalExprSwitchContext((Node *) test_expr, econtext,
|
||||
econtext = MakeExprContext(NULL, CurrentMemoryContext);
|
||||
test_result = ExecEvalExprSwitchContext(test_exprstate, econtext,
|
||||
&isNull, NULL);
|
||||
FreeExprContext(econtext);
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.117 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.118 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -1315,7 +1315,18 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
|
||||
simple = simplify_function(expr->opfuncid, args,
|
||||
false, active_fns);
|
||||
if (simple) /* successfully simplified it */
|
||||
return (Node *) simple;
|
||||
{
|
||||
/*
|
||||
* Since the underlying operator is "=", must negate its
|
||||
* result
|
||||
*/
|
||||
Const *csimple = (Const *) simple;
|
||||
|
||||
Assert(IsA(csimple, Const));
|
||||
csimple->constvalue =
|
||||
BoolGetDatum(!DatumGetBool(csimple->constvalue));
|
||||
return (Node *) csimple;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1672,6 +1683,7 @@ evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
|
||||
bool has_nonconst_input = false;
|
||||
bool has_null_input = false;
|
||||
FuncExpr *newexpr;
|
||||
ExprState *newexprstate;
|
||||
ExprContext *econtext;
|
||||
Datum const_val;
|
||||
bool const_is_null;
|
||||
@@ -1738,7 +1750,9 @@ evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
|
||||
*/
|
||||
econtext = MakeExprContext(NULL, CurrentMemoryContext);
|
||||
|
||||
const_val = ExecEvalExprSwitchContext((Node *) newexpr, econtext,
|
||||
newexprstate = ExecInitExpr((Expr *) newexpr, NULL);
|
||||
|
||||
const_val = ExecEvalExprSwitchContext(newexprstate, econtext,
|
||||
&const_is_null, NULL);
|
||||
|
||||
/* Must copy result out of sub-context used by expression eval */
|
||||
@@ -1746,7 +1760,6 @@ evaluate_function(Oid funcid, List *args, HeapTuple func_tuple)
|
||||
const_val = datumCopy(const_val, resultTypByVal, resultTypLen);
|
||||
|
||||
FreeExprContext(econtext);
|
||||
pfree(newexpr);
|
||||
|
||||
/*
|
||||
* Make the constant result node.
|
||||
|
@@ -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.256 2002/12/12 20:35:12 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.257 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "commands/prepare.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "optimizer/planmain.h"
|
||||
#include "parser/analyze.h"
|
||||
#include "parser/gramparse.h"
|
||||
#include "parser/parsetree.h"
|
||||
@@ -2424,8 +2423,6 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
|
||||
format_type_be(given_type_id),
|
||||
format_type_be(expected_type_id));
|
||||
|
||||
fix_opfuncids(expr);
|
||||
|
||||
lfirst(l) = expr;
|
||||
|
||||
paramtypes = lnext(paramtypes);
|
||||
|
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.54 2002/09/04 20:31:29 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.55 2002/12/13 19:45:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "executor/executor.h"
|
||||
#include "utils/fcache.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/sets.h"
|
||||
#include "utils/syscache.h"
|
||||
@@ -143,7 +142,7 @@ Datum
|
||||
seteval(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid funcoid = PG_GETARG_OID(0);
|
||||
FunctionCachePtr fcache;
|
||||
FuncExprState *fcache;
|
||||
Datum result;
|
||||
bool isNull;
|
||||
ExprDoneCond isDone;
|
||||
@@ -152,10 +151,27 @@ seteval(PG_FUNCTION_ARGS)
|
||||
* If this is the first call, we need to set up the fcache for the
|
||||
* target set's function.
|
||||
*/
|
||||
fcache = (FunctionCachePtr) fcinfo->flinfo->fn_extra;
|
||||
fcache = (FuncExprState *) fcinfo->flinfo->fn_extra;
|
||||
if (fcache == NULL)
|
||||
{
|
||||
fcache = init_fcache(funcoid, 0, fcinfo->flinfo->fn_mcxt);
|
||||
MemoryContext oldcontext;
|
||||
FuncExpr *func;
|
||||
|
||||
oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
|
||||
|
||||
func = makeNode(FuncExpr);
|
||||
func->funcid = funcoid;
|
||||
func->funcresulttype = InvalidOid; /* nothing will look at this */
|
||||
func->funcretset = true;
|
||||
func->funcformat = COERCE_EXPLICIT_CALL;
|
||||
func->args = NIL; /* there are no arguments */
|
||||
|
||||
fcache = (FuncExprState *) ExecInitExpr((Expr *) func, NULL);
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
init_fcache(funcoid, fcache, fcinfo->flinfo->fn_mcxt);
|
||||
|
||||
fcinfo->flinfo->fn_extra = (void *) fcache;
|
||||
}
|
||||
|
||||
@@ -169,22 +185,10 @@ seteval(PG_FUNCTION_ARGS)
|
||||
isDone = ExprSingleResult;
|
||||
|
||||
result = ExecMakeFunctionResult(fcache,
|
||||
NIL,
|
||||
NULL, /* no econtext, see above */
|
||||
&isNull,
|
||||
&isDone);
|
||||
|
||||
/*
|
||||
* If we're done with the results of this set function, get rid of its
|
||||
* func cache so that we will start from the top next time. (Can you
|
||||
* say "memory leak"? This feature is a crock anyway...)
|
||||
*/
|
||||
if (isDone != ExprMultipleResult)
|
||||
{
|
||||
pfree(fcache);
|
||||
fcinfo->flinfo->fn_extra = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return isNull/isDone status.
|
||||
*/
|
||||
|
5
src/backend/utils/cache/Makefile
vendored
5
src/backend/utils/cache/Makefile
vendored
@@ -4,7 +4,7 @@
|
||||
# Makefile for utils/cache
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.16 2002/03/31 06:26:31 tgl Exp $
|
||||
# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.17 2002/12/13 19:45:56 tgl Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -12,8 +12,7 @@ subdir = src/backend/utils/cache
|
||||
top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = catcache.o inval.o relcache.o syscache.o lsyscache.o \
|
||||
fcache.o
|
||||
OBJS = catcache.o inval.o relcache.o syscache.o lsyscache.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
53
src/backend/utils/cache/fcache.c
vendored
53
src/backend/utils/cache/fcache.c
vendored
@@ -1,53 +0,0 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* fcache.c
|
||||
* Code for the 'function cache' used in Oper and Func nodes.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.45 2002/06/20 20:29:39 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "miscadmin.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/fcache.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
||||
|
||||
/*
|
||||
* Build a 'FunctionCache' struct given the PG_PROC oid.
|
||||
*/
|
||||
FunctionCachePtr
|
||||
init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
|
||||
{
|
||||
FunctionCachePtr retval;
|
||||
AclResult aclresult;
|
||||
|
||||
/* Check permission to call function */
|
||||
aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, get_func_name(foid));
|
||||
|
||||
/* Safety check (should never fail, as parser should check sooner) */
|
||||
if (nargs > FUNC_MAX_ARGS)
|
||||
elog(ERROR, "init_fcache: too many arguments");
|
||||
|
||||
/* Create fcache entry in the desired context */
|
||||
retval = (FunctionCachePtr) MemoryContextAlloc(fcacheCxt,
|
||||
sizeof(FunctionCache));
|
||||
MemSet(retval, 0, sizeof(FunctionCache));
|
||||
|
||||
/* Set up the primary fmgr lookup information */
|
||||
fmgr_info_cxt(foid, &(retval->func), fcacheCxt);
|
||||
|
||||
/* Initialize additional info */
|
||||
retval->setArgsValid = false;
|
||||
|
||||
return retval;
|
||||
}
|
Reference in New Issue
Block a user