diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 376 | ||||
-rw-r--r-- | src/backend/executor/execQual.c | 3 | ||||
-rw-r--r-- | src/backend/executor/execTuples.c | 20 | ||||
-rw-r--r-- | src/backend/executor/execUtils.c | 40 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 3 | ||||
-rw-r--r-- | src/backend/executor/nodeAppend.c | 194 | ||||
-rw-r--r-- | src/backend/executor/nodeSeqscan.c | 4 |
7 files changed, 258 insertions, 382 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index a26acc9a763..d9d02654970 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.131 2000/10/26 21:35:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.132 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,6 +50,10 @@ static TupleDesc InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate); +static void initResultRelInfo(ResultRelInfo *resultRelInfo, + Index resultRelationIndex, + List *rangeTable, + CmdType operation); static void EndPlan(Plan *plan, EState *estate); static TupleTableSlot *ExecutePlan(EState *estate, Plan *plan, CmdType operation, @@ -310,10 +314,6 @@ ExecCheckQueryPerms(CmdType operation, Query *parseTree, Plan *plan) * ExecCheckPlanPerms * Recursively scan the plan tree to check access permissions in * subplans. - * - * We also need to look at the local rangetables in Append plan nodes, - * which is pretty bogus --- most likely, those tables should be mentioned - * in the query's main rangetable. But at the moment, they're not. */ static void ExecCheckPlanPerms(Plan *plan, List *rangeTable, CmdType operation) @@ -365,27 +365,11 @@ ExecCheckPlanPerms(Plan *plan, List *rangeTable, CmdType operation) Append *app = (Append *) plan; List *appendplans; - if (app->inheritrelid > 0) + foreach(appendplans, app->appendplans) { - /* Append implements expansion of inheritance */ - ExecCheckRTPerms(app->inheritrtable, operation); - - foreach(appendplans, app->appendplans) - { - ExecCheckPlanPerms((Plan *) lfirst(appendplans), - rangeTable, - operation); - } - } - else - { - /* Append implements UNION, which must be a SELECT */ - foreach(appendplans, app->appendplans) - { - ExecCheckPlanPerms((Plan *) lfirst(appendplans), - rangeTable, - CMD_SELECT); - } + ExecCheckPlanPerms((Plan *) lfirst(appendplans), + rangeTable, + operation); } break; } @@ -518,10 +502,8 @@ static TupleDesc InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) { List *rangeTable; - int resultRelation; Relation intoRelationDesc; TupleDesc tupType; - List *targetList; /* * Do permissions checks. @@ -532,7 +514,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) * get information from query descriptor */ rangeTable = parseTree->rtable; - resultRelation = parseTree->resultRelation; /* * initialize the node's execution state @@ -540,63 +521,61 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) estate->es_range_table = rangeTable; /* - * initialize result relation stuff + * if there is a result relation, initialize result relation stuff */ - - if (resultRelation != 0 && operation != CMD_SELECT) + if (parseTree->resultRelation != 0 && operation != CMD_SELECT) { + List *resultRelations = parseTree->resultRelations; + int numResultRelations; + ResultRelInfo *resultRelInfos; - /* - * if we have a result relation, open it and initialize the result - * relation info stuff. - */ - RelationInfo *resultRelationInfo; - Index resultRelationIndex; - Oid resultRelationOid; - Relation resultRelationDesc; - - resultRelationIndex = resultRelation; - resultRelationOid = getrelid(resultRelationIndex, rangeTable); - resultRelationDesc = heap_open(resultRelationOid, RowExclusiveLock); - - if (resultRelationDesc->rd_rel->relkind == RELKIND_SEQUENCE) - elog(ERROR, "You can't change sequence relation %s", - RelationGetRelationName(resultRelationDesc)); - - if (resultRelationDesc->rd_rel->relkind == RELKIND_TOASTVALUE) - elog(ERROR, "You can't change toast relation %s", - RelationGetRelationName(resultRelationDesc)); - - if (resultRelationDesc->rd_rel->relkind == RELKIND_VIEW) - elog(ERROR, "You can't change view relation %s", - RelationGetRelationName(resultRelationDesc)); - - resultRelationInfo = makeNode(RelationInfo); - resultRelationInfo->ri_RangeTableIndex = resultRelationIndex; - resultRelationInfo->ri_RelationDesc = resultRelationDesc; - resultRelationInfo->ri_NumIndices = 0; - resultRelationInfo->ri_IndexRelationDescs = NULL; - resultRelationInfo->ri_IndexRelationInfo = NULL; + if (resultRelations != NIL) + { + /* + * Multiple result relations (due to inheritance) + * parseTree->resultRelations identifies them all + */ + ResultRelInfo *resultRelInfo; - /* - * If there are indices on the result relation, open them and save - * descriptors in the result relation info, so that we can add new - * index entries for the tuples we add/update. We need not do - * this for a DELETE, however, since deletion doesn't affect - * indexes. - */ - if (resultRelationDesc->rd_rel->relhasindex && - operation != CMD_DELETE) - ExecOpenIndices(resultRelationInfo); + numResultRelations = length(resultRelations); + resultRelInfos = (ResultRelInfo *) + palloc(numResultRelations * sizeof(ResultRelInfo)); + resultRelInfo = resultRelInfos; + while (resultRelations != NIL) + { + initResultRelInfo(resultRelInfo, + lfirsti(resultRelations), + rangeTable, + operation); + resultRelInfo++; + resultRelations = lnext(resultRelations); + } + } + else + { + /* + * Single result relation identified by parseTree->resultRelation + */ + numResultRelations = 1; + resultRelInfos = (ResultRelInfo *) palloc(sizeof(ResultRelInfo)); + initResultRelInfo(resultRelInfos, + parseTree->resultRelation, + rangeTable, + operation); + } - estate->es_result_relation_info = resultRelationInfo; + estate->es_result_relations = resultRelInfos; + estate->es_num_result_relations = numResultRelations; + /* Initialize to first or only result rel */ + estate->es_result_relation_info = resultRelInfos; } else { - /* * if no result relation, then set state appropriately */ + estate->es_result_relations = NULL; + estate->es_num_result_relations = 0; estate->es_result_relation_info = NULL; } @@ -642,19 +621,17 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) ExecInitNode(plan, estate, NULL); /* - * get the tuple descriptor describing the type of tuples to return.. + * Get the tuple descriptor describing the type of tuples to return. * (this is especially important if we are creating a relation with * "retrieve into") */ tupType = ExecGetTupType(plan); /* tuple descriptor */ - targetList = plan->targetlist; /* - * Now that we have the target list, initialize the junk filter if - * needed. SELECT and INSERT queries need a filter if there are any - * junk attrs in the tlist. UPDATE and DELETE always need one, since - * there's always a junk 'ctid' attribute present --- no need to look - * first. + * Initialize the junk filter if needed. SELECT and INSERT queries need + * a filter if there are any junk attrs in the tlist. UPDATE and + * DELETE always need one, since there's always a junk 'ctid' attribute + * present --- no need to look first. */ { bool junk_filter_needed = false; @@ -664,7 +641,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) { case CMD_SELECT: case CMD_INSERT: - foreach(tlist, targetList) + foreach(tlist, plan->targetlist) { TargetEntry *tle = (TargetEntry *) lfirst(tlist); @@ -685,12 +662,55 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) if (junk_filter_needed) { - JunkFilter *j = ExecInitJunkFilter(targetList, tupType); + /* + * If there are multiple result relations, each one needs + * its own junk filter. Note this is only possible for + * UPDATE/DELETE, so we can't be fooled by some needing + * a filter and some not. + */ + if (parseTree->resultRelations != NIL) + { + List *subplans; + ResultRelInfo *resultRelInfo; + + /* Top plan had better be an Append here. */ + Assert(IsA(plan, Append)); + Assert(((Append *) plan)->isTarget); + subplans = ((Append *) plan)->appendplans; + Assert(length(subplans) == estate->es_num_result_relations); + resultRelInfo = estate->es_result_relations; + while (subplans != NIL) + { + Plan *subplan = (Plan *) lfirst(subplans); + JunkFilter *j; + + j = ExecInitJunkFilter(subplan->targetlist, + ExecGetTupType(subplan)); + resultRelInfo->ri_junkFilter = j; + resultRelInfo++; + subplans = lnext(subplans); + } + /* + * Set active junkfilter too; at this point ExecInitAppend + * has already selected an active result relation... + */ + estate->es_junkFilter = + estate->es_result_relation_info->ri_junkFilter; + } + else + { + /* Normal case with just one JunkFilter */ + JunkFilter *j = ExecInitJunkFilter(plan->targetlist, + tupType); - estate->es_junkFilter = j; + estate->es_junkFilter = j; + if (estate->es_result_relation_info) + estate->es_result_relation_info->ri_junkFilter = j; - if (operation == CMD_SELECT) - tupType = j->jf_cleanTupType; + /* For SELECT, want to return the cleaned tuple type */ + if (operation == CMD_SELECT) + tupType = j->jf_cleanTupType; + } } else estate->es_junkFilter = NULL; @@ -762,6 +782,59 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) return tupType; } +/* + * Initialize ResultRelInfo data for one result relation + */ +static void +initResultRelInfo(ResultRelInfo *resultRelInfo, + Index resultRelationIndex, + List *rangeTable, + CmdType operation) +{ + Oid resultRelationOid; + Relation resultRelationDesc; + + resultRelationOid = getrelid(resultRelationIndex, rangeTable); + resultRelationDesc = heap_open(resultRelationOid, RowExclusiveLock); + + switch (resultRelationDesc->rd_rel->relkind) + { + case RELKIND_SEQUENCE: + elog(ERROR, "You can't change sequence relation %s", + RelationGetRelationName(resultRelationDesc)); + break; + case RELKIND_TOASTVALUE: + elog(ERROR, "You can't change toast relation %s", + RelationGetRelationName(resultRelationDesc)); + break; + case RELKIND_VIEW: + elog(ERROR, "You can't change view relation %s", + RelationGetRelationName(resultRelationDesc)); + break; + } + + MemSet(resultRelInfo, 0, sizeof(ResultRelInfo)); + resultRelInfo->type = T_ResultRelInfo; + resultRelInfo->ri_RangeTableIndex = resultRelationIndex; + resultRelInfo->ri_RelationDesc = resultRelationDesc; + resultRelInfo->ri_NumIndices = 0; + resultRelInfo->ri_IndexRelationDescs = NULL; + resultRelInfo->ri_IndexRelationInfo = NULL; + resultRelInfo->ri_ConstraintExprs = NULL; + resultRelInfo->ri_junkFilter = NULL; + + /* + * If there are indices on the result relation, open them and save + * descriptors in the result relation info, so that we can add new + * index entries for the tuples we add/update. We need not do + * this for a DELETE, however, since deletion doesn't affect + * indexes. + */ + if (resultRelationDesc->rd_rel->relhasindex && + operation != CMD_DELETE) + ExecOpenIndices(resultRelInfo); +} + /* ---------------------------------------------------------------- * EndPlan * @@ -771,7 +844,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) static void EndPlan(Plan *plan, EState *estate) { - RelationInfo *resultRelationInfo; + ResultRelInfo *resultRelInfo; + int i; List *l; /* @@ -792,16 +866,16 @@ EndPlan(Plan *plan, EState *estate) estate->es_tupleTable = NULL; /* - * close the result relation if necessary, but hold lock on it - * until xact commit. NB: must not do this till after ExecEndNode(), - * see nodeAppend.c ... + * close the result relation(s) if any, but hold locks + * until xact commit. */ - resultRelationInfo = estate->es_result_relation_info; - if (resultRelationInfo != NULL) + resultRelInfo = estate->es_result_relations; + for (i = estate->es_num_result_relations; i > 0; i--) { - heap_close(resultRelationInfo->ri_RelationDesc, NoLock); - /* close indices on the result relation, too */ - ExecCloseIndices(resultRelationInfo); + /* Close indices and then the relation itself */ + ExecCloseIndices(resultRelInfo); + heap_close(resultRelInfo->ri_RelationDesc, NoLock); + resultRelInfo++; } /* @@ -1116,7 +1190,7 @@ ExecAppend(TupleTableSlot *slot, EState *estate) { HeapTuple tuple; - RelationInfo *resultRelationInfo; + ResultRelInfo *resultRelInfo; Relation resultRelationDesc; int numIndices; Oid newId; @@ -1127,10 +1201,10 @@ ExecAppend(TupleTableSlot *slot, tuple = slot->val; /* - * get information on the result relation + * get information on the (current) result relation */ - resultRelationInfo = estate->es_result_relation_info; - resultRelationDesc = resultRelationInfo->ri_RelationDesc; + resultRelInfo = estate->es_result_relation_info; + resultRelationDesc = resultRelInfo->ri_RelationDesc; /* BEFORE ROW INSERT Triggers */ if (resultRelationDesc->trigdesc && @@ -1154,9 +1228,8 @@ ExecAppend(TupleTableSlot *slot, /* * Check the constraints of the tuple */ - if (resultRelationDesc->rd_att->constr) - ExecConstraints("ExecAppend", resultRelationDesc, slot, estate); + ExecConstraints("ExecAppend", resultRelInfo, slot, estate); /* * insert the tuple @@ -1174,7 +1247,7 @@ ExecAppend(TupleTableSlot *slot, * the tupleid of the new tuple is placed in the new tuple's t_ctid * field. */ - numIndices = resultRelationInfo->ri_NumIndices; + numIndices = resultRelInfo->ri_NumIndices; if (numIndices > 0) ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false); @@ -1195,16 +1268,16 @@ ExecDelete(TupleTableSlot *slot, ItemPointer tupleid, EState *estate) { - RelationInfo *resultRelationInfo; + ResultRelInfo *resultRelInfo; Relation resultRelationDesc; ItemPointerData ctid; int result; /* - * get the result relation information + * get information on the (current) result relation */ - resultRelationInfo = estate->es_result_relation_info; - resultRelationDesc = resultRelationInfo->ri_RelationDesc; + resultRelInfo = estate->es_result_relation_info; + resultRelationDesc = resultRelInfo->ri_RelationDesc; /* BEFORE ROW DELETE Triggers */ if (resultRelationDesc->trigdesc && @@ -1237,7 +1310,7 @@ ldelete:; else if (!(ItemPointerEquals(tupleid, &ctid))) { TupleTableSlot *epqslot = EvalPlanQual(estate, - resultRelationInfo->ri_RangeTableIndex, &ctid); + resultRelInfo->ri_RangeTableIndex, &ctid); if (!TupIsNull(epqslot)) { @@ -1287,7 +1360,7 @@ ExecReplace(TupleTableSlot *slot, EState *estate) { HeapTuple tuple; - RelationInfo *resultRelationInfo; + ResultRelInfo *resultRelInfo; Relation resultRelationDesc; ItemPointerData ctid; int result; @@ -1308,10 +1381,10 @@ ExecReplace(TupleTableSlot *slot, tuple = slot->val; /* - * get the result relation information + * get information on the (current) result relation */ - resultRelationInfo = estate->es_result_relation_info; - resultRelationDesc = resultRelationInfo->ri_RelationDesc; + resultRelInfo = estate->es_result_relation_info; + resultRelationDesc = resultRelInfo->ri_RelationDesc; /* BEFORE ROW UPDATE Triggers */ if (resultRelationDesc->trigdesc && @@ -1335,9 +1408,8 @@ ExecReplace(TupleTableSlot *slot, /* * Check the constraints of the tuple */ - if (resultRelationDesc->rd_att->constr) - ExecConstraints("ExecReplace", resultRelationDesc, slot, estate); + ExecConstraints("ExecReplace", resultRelInfo, slot, estate); /* * replace the heap tuple @@ -1358,7 +1430,7 @@ lreplace:; else if (!(ItemPointerEquals(tupleid, &ctid))) { TupleTableSlot *epqslot = EvalPlanQual(estate, - resultRelationInfo->ri_RangeTableIndex, &ctid); + resultRelInfo->ri_RangeTableIndex, &ctid); if (!TupIsNull(epqslot)) { @@ -1396,7 +1468,7 @@ lreplace:; * there. */ - numIndices = resultRelationInfo->ri_NumIndices; + numIndices = resultRelInfo->ri_NumIndices; if (numIndices > 0) ExecInsertIndexTuples(slot, &(tuple->t_self), estate, true); @@ -1406,8 +1478,10 @@ lreplace:; } static char * -ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate) +ExecRelCheck(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate) { + Relation rel = resultRelInfo->ri_RelationDesc; int ncheck = rel->rd_att->constr->num_check; ConstrCheck *check = rel->rd_att->constr->check; ExprContext *econtext; @@ -1416,6 +1490,24 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate) int i; /* + * If first time through for this result relation, build expression + * nodetrees for rel's constraint expressions. Keep them in the + * per-query memory context so they'll survive throughout the query. + */ + if (resultRelInfo->ri_ConstraintExprs == NULL) + { + oldContext = MemoryContextSwitchTo(estate->es_query_cxt); + resultRelInfo->ri_ConstraintExprs = + (List **) palloc(ncheck * sizeof(List *)); + for (i = 0; i < ncheck; i++) + { + qual = (List *) stringToNode(check[i].ccbin); + resultRelInfo->ri_ConstraintExprs[i] = qual; + } + MemoryContextSwitchTo(oldContext); + } + + /* * We will use the EState's per-tuple context for evaluating constraint * expressions. Create it if it's not already there; if it is, reset it * to free previously-used storage. @@ -1431,58 +1523,13 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate) else ResetExprContext(econtext); - /* - * If first time through for current result relation, set up econtext's - * range table to refer to result rel, and build expression nodetrees - * for rel's constraint expressions. All this stuff is kept in the - * per-query memory context so it will still be here next time through. - * - * NOTE: if there are multiple result relations (eg, due to inheritance) - * then we leak storage for prior rel's expressions and rangetable. - * This should not be a big problem as long as result rels are processed - * sequentially within a command. - */ - if (econtext->ecxt_range_table == NIL || - getrelid(1, econtext->ecxt_range_table) != RelationGetRelid(rel)) - { - RangeTblEntry *rte; - - /* - * Make sure expressions, etc are placed in appropriate context. - */ - oldContext = MemoryContextSwitchTo(estate->es_query_cxt); - - rte = makeNode(RangeTblEntry); - - rte->relname = RelationGetRelationName(rel); - rte->relid = RelationGetRelid(rel); - rte->eref = makeNode(Attr); - rte->eref->relname = rte->relname; - /* other fields won't be used, leave them zero */ - - /* Set up single-entry range table */ - econtext->ecxt_range_table = makeList1(rte); - - estate->es_result_relation_constraints = - (List **) palloc(ncheck * sizeof(List *)); - - for (i = 0; i < ncheck; i++) - { - qual = (List *) stringToNode(check[i].ccbin); - estate->es_result_relation_constraints[i] = qual; - } - - /* Done with building long-lived items */ - MemoryContextSwitchTo(oldContext); - } - /* Arrange for econtext's scan tuple to be the tuple under test */ econtext->ecxt_scantuple = slot; /* And evaluate the constraints */ for (i = 0; i < ncheck; i++) { - qual = estate->es_result_relation_constraints[i]; + qual = resultRelInfo->ri_ConstraintExprs[i]; /* * NOTE: SQL92 specifies that a NULL result from a constraint @@ -1498,9 +1545,10 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate) } void -ExecConstraints(char *caller, Relation rel, +ExecConstraints(char *caller, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate) { + Relation rel = resultRelInfo->ri_RelationDesc; HeapTuple tuple = slot->val; TupleConstr *constr = rel->rd_att->constr; @@ -1524,7 +1572,7 @@ ExecConstraints(char *caller, Relation rel, { char *failed; - if ((failed = ExecRelCheck(rel, slot, estate)) != NULL) + if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL) elog(ERROR, "%s: rejected due to CHECK constraint %s", caller, failed); } diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 622ea2ef82c..beeff0db331 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.80 2000/08/24 23:34:09 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.81 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -341,7 +341,6 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull) tempSlot->ttc_descIsNew = true; tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL; tempSlot->ttc_buffer = InvalidBuffer; - tempSlot->ttc_whichplan = -1; tup = heap_copytuple(heapTuple); td = CreateTupleDescCopy(tuple_type); diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 408716abf83..65eef4141f4 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.42 2000/10/26 21:35:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.43 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -303,7 +303,6 @@ ExecAllocTableSlot(TupleTable table) slot->ttc_descIsNew = true; slot->ttc_tupleDescriptor = (TupleDesc) NULL; slot->ttc_buffer = InvalidBuffer; - slot->ttc_whichplan = -1; return slot; } @@ -675,20 +674,11 @@ NodeGetResultTupleSlot(Plan *node) case T_Append: { - Append *n = (Append *) node; - AppendState *appendstate; - List *appendplans; - int whichplan; - Plan *subplan; - - appendstate = n->appendstate; - appendplans = n->appendplans; - whichplan = appendstate->as_whichplan; - - subplan = (Plan *) nth(whichplan, appendplans); - slot = NodeGetResultTupleSlot(subplan); - break; + AppendState *appendstate = ((Append *) node)->appendstate; + + slot = appendstate->cstate.cs_ResultTupleSlot; } + break; case T_IndexScan: { diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 4eff4a07bb2..ecdda594188 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.67 2000/10/05 19:48:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.68 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -172,7 +172,6 @@ ExecAssignExprContext(EState *estate, CommonState *commonstate) econtext->ecxt_param_list_info = estate->es_param_list_info; econtext->ecxt_aggvalues = NULL; econtext->ecxt_aggnulls = NULL; - econtext->ecxt_range_table = estate->es_range_table; commonstate->cs_ExprContext = econtext; } @@ -215,7 +214,6 @@ MakeExprContext(TupleTableSlot *slot, econtext->ecxt_param_list_info = NULL; econtext->ecxt_aggvalues = NULL; econtext->ecxt_aggnulls = NULL; - econtext->ecxt_range_table = NIL; return econtext; } @@ -649,10 +647,10 @@ QueryDescGetTypeInfo(QueryDesc *queryDesc) * ExecOpenIndices * * Find the indices associated with a result relation, open them, - * and save information about them in the result RelationInfo. + * and save information about them in the result ResultRelInfo. * * At entry, caller has already opened and locked - * resultRelationInfo->ri_RelationDesc. + * resultRelInfo->ri_RelationDesc. * * This used to be horribly ugly code, and slow too because it * did a sequential scan of pg_index. Now we rely on the relcache @@ -662,9 +660,9 @@ QueryDescGetTypeInfo(QueryDesc *queryDesc) * ---------------------------------------------------------------- */ void -ExecOpenIndices(RelationInfo *resultRelationInfo) +ExecOpenIndices(ResultRelInfo *resultRelInfo) { - Relation resultRelation = resultRelationInfo->ri_RelationDesc; + Relation resultRelation = resultRelInfo->ri_RelationDesc; List *indexoidlist, *indexoidscan; int len, @@ -672,7 +670,7 @@ ExecOpenIndices(RelationInfo *resultRelationInfo) RelationPtr relationDescs; IndexInfo **indexInfoArray; - resultRelationInfo->ri_NumIndices = 0; + resultRelInfo->ri_NumIndices = 0; /* checks for disabled indexes */ if (! RelationGetForm(resultRelation)->relhasindex) @@ -697,9 +695,9 @@ ExecOpenIndices(RelationInfo *resultRelationInfo) relationDescs = (RelationPtr) palloc(len * sizeof(Relation)); indexInfoArray = (IndexInfo **) palloc(len * sizeof(IndexInfo *)); - resultRelationInfo->ri_NumIndices = len; - resultRelationInfo->ri_IndexRelationDescs = relationDescs; - resultRelationInfo->ri_IndexRelationInfo = indexInfoArray; + resultRelInfo->ri_NumIndices = len; + resultRelInfo->ri_IndexRelationDescs = relationDescs; + resultRelInfo->ri_IndexRelationInfo = indexInfoArray; /* ---------------- * For each index, open the index relation and save pg_index info. @@ -765,18 +763,18 @@ ExecOpenIndices(RelationInfo *resultRelationInfo) /* ---------------------------------------------------------------- * ExecCloseIndices * - * Close the index relations stored in resultRelationInfo + * Close the index relations stored in resultRelInfo * ---------------------------------------------------------------- */ void -ExecCloseIndices(RelationInfo *resultRelationInfo) +ExecCloseIndices(ResultRelInfo *resultRelInfo) { int i; int numIndices; RelationPtr relationDescs; - numIndices = resultRelationInfo->ri_NumIndices; - relationDescs = resultRelationInfo->ri_IndexRelationDescs; + numIndices = resultRelInfo->ri_NumIndices; + relationDescs = resultRelInfo->ri_IndexRelationDescs; for (i = 0; i < numIndices; i++) { @@ -817,7 +815,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot, bool is_update) { HeapTuple heapTuple; - RelationInfo *resultRelationInfo; + ResultRelInfo *resultRelInfo; int i; int numIndices; RelationPtr relationDescs; @@ -833,11 +831,11 @@ ExecInsertIndexTuples(TupleTableSlot *slot, /* * Get information from the result relation info structure. */ - resultRelationInfo = estate->es_result_relation_info; - numIndices = resultRelationInfo->ri_NumIndices; - relationDescs = resultRelationInfo->ri_IndexRelationDescs; - indexInfoArray = resultRelationInfo->ri_IndexRelationInfo; - heapRelation = resultRelationInfo->ri_RelationDesc; + resultRelInfo = estate->es_result_relation_info; + numIndices = resultRelInfo->ri_NumIndices; + relationDescs = resultRelInfo->ri_IndexRelationDescs; + indexInfoArray = resultRelInfo->ri_IndexRelationInfo; + heapRelation = resultRelInfo->ri_RelationDesc; heapDescriptor = RelationGetDescr(heapRelation); /* diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index e5a5e55ef8d..ca9c48e294d 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.39 2000/10/26 21:35:15 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.40 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -253,7 +253,6 @@ init_sql_fcache(FmgrInfo *finfo) slot->ttc_descIsNew = true; slot->ttc_tupleDescriptor = (TupleDesc) NULL; slot->ttc_buffer = InvalidBuffer; - slot->ttc_whichplan = -1; fcache->funcSlot = slot; } diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 81eeb1e8b0b..e47ec5756cb 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.37 2000/11/09 18:12:53 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.38 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,8 +36,8 @@ * nil nil ... ... ... * subplans * - * Append nodes are currently used for unions, and to support inheritance - * queries, where several relations need to be scanned. + * Append nodes are currently used for unions, and to support + * inheritance queries, where several relations need to be scanned. * For example, in our standard person/student/employee/student-emp * example, where student and employee inherit from person * and student-emp inherits from student and employee, the @@ -54,8 +54,8 @@ * | | | | * person employee student student-emp */ -#include "postgres.h" +#include "postgres.h" #include "access/heapam.h" #include "executor/execdebug.h" @@ -78,12 +78,8 @@ exec_append_initialize_next(Append *node) { EState *estate; AppendState *appendstate; - TupleTableSlot *result_slot; - List *rangeTable; int whichplan; int nplans; - List *inheritrtable; - RangeTblEntry *rtentry; /* ---------------- * get information from the append node @@ -91,12 +87,8 @@ exec_append_initialize_next(Append *node) */ estate = node->plan.state; appendstate = node->appendstate; - result_slot = appendstate->cstate.cs_ResultTupleSlot; - rangeTable = estate->es_range_table; - whichplan = appendstate->as_whichplan; nplans = appendstate->as_nplans; - inheritrtable = node->inheritrtable; if (whichplan < 0) { @@ -110,7 +102,6 @@ exec_append_initialize_next(Append *node) */ appendstate->as_whichplan = 0; return FALSE; - } else if (whichplan >= nplans) { @@ -121,37 +112,25 @@ exec_append_initialize_next(Append *node) */ appendstate->as_whichplan = nplans - 1; return FALSE; - } else { /* ---------------- * initialize the scan - * (and update the range table appropriately) * - * (doesn't this leave the range table hosed for anybody upstream - * of the Append node??? - jolly ) + * If we are controlling the target relation, select the proper + * active ResultRelInfo and junk filter for this target. * ---------------- */ - if (node->inheritrelid > 0) + if (node->isTarget) { - rtentry = nth(whichplan, inheritrtable); - Assert(rtentry != NULL); - rt_store(node->inheritrelid, rangeTable, rtentry); + Assert(whichplan < estate->es_num_result_relations); + estate->es_result_relation_info = + estate->es_result_relations + whichplan; + estate->es_junkFilter = + estate->es_result_relation_info->ri_junkFilter; } - if (appendstate->as_junkFilter_list) - { - estate->es_junkFilter = (JunkFilter *) nth(whichplan, - appendstate->as_junkFilter_list); - } - if (appendstate->as_result_relation_info_list) - { - estate->es_result_relation_info = (RelationInfo *) nth(whichplan, - appendstate->as_result_relation_info_list); - } - result_slot->ttc_whichplan = whichplan; - return TRUE; } } @@ -176,14 +155,10 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent) { AppendState *appendstate; int nplans; - List *inheritrtable; List *appendplans; bool *initialized; int i; Plan *initNode; - List *junkList; - RelationInfo *es_rri = estate->es_result_relation_info; - bool inherited_result_rel = false; CXT1_printf("ExecInitAppend: context is %d\n", CurrentMemoryContext); @@ -196,7 +171,6 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent) appendplans = node->appendplans; nplans = length(appendplans); - inheritrtable = node->inheritrtable; initialized = (bool *) palloc(nplans * sizeof(bool)); MemSet(initialized, 0, nplans * sizeof(bool)); @@ -228,119 +202,25 @@ ExecInitAppend(Append *node, EState *estate, Plan *parent) */ ExecInitResultTupleSlot(estate, &appendstate->cstate); - /* - * If the inherits rtentry is the result relation, we have to make a - * result relation info list for all inheritors so we can update their - * indices and put the result tuples in the right place etc. - * - * e.g. replace p (age = p.age + 1) from p in person* - */ - if ((es_rri != (RelationInfo *) NULL) && - (node->inheritrelid == es_rri->ri_RangeTableIndex)) - { - List *resultList = NIL; - Oid initial_reloid = RelationGetRelid(es_rri->ri_RelationDesc); - List *rtentryP; - - inherited_result_rel = true; - - foreach(rtentryP, inheritrtable) - { - RangeTblEntry *rtentry = lfirst(rtentryP); - Oid reloid = rtentry->relid; - RelationInfo *rri; - - /* - * We must recycle the RelationInfo already opened by InitPlan() - * for the parent rel, else we will leak the associated relcache - * refcount. - */ - if (reloid == initial_reloid) - { - Assert(es_rri != NULL); /* check we didn't use it already */ - rri = es_rri; - es_rri = NULL; - } - else - { - rri = makeNode(RelationInfo); - rri->ri_RangeTableIndex = node->inheritrelid; - rri->ri_RelationDesc = heap_open(reloid, RowExclusiveLock); - rri->ri_NumIndices = 0; - rri->ri_IndexRelationDescs = NULL; /* index descs */ - rri->ri_IndexRelationInfo = NULL; /* index key info */ - - /* - * XXX if the operation is a DELETE then we need not open - * indices, but how to tell that here? - */ - if (rri->ri_RelationDesc->rd_rel->relhasindex) - ExecOpenIndices(rri); - } - - /* - * NB: the as_result_relation_info_list must be in the same - * order as the rtentry list otherwise update or delete on - * inheritance hierarchies won't work. - */ - resultList = lappend(resultList, rri); - } - - appendstate->as_result_relation_info_list = resultList; - /* Check that we recycled InitPlan()'s RelationInfo */ - Assert(es_rri == NULL); - /* Just for paranoia's sake, clear link until we set it properly */ - estate->es_result_relation_info = NULL; - } - /* ---------------- * call ExecInitNode on each of the plans in our list * and save the results into the array "initialized" * ---------------- */ - junkList = NIL; - for (i = 0; i < nplans; i++) { - /* ---------------- - * NOTE: we first modify range table in - * exec_append_initialize_next() and - * then initialize the subnode, - * since it may use the range table. - * ---------------- - */ appendstate->as_whichplan = i; exec_append_initialize_next(node); initNode = (Plan *) nth(i, appendplans); initialized[i] = ExecInitNode(initNode, estate, (Plan *) node); - - /* --------------- - * Each targetlist in the subplan may need its own junk filter - * - * This is true only when the reln being replaced/deleted is - * the one that we're looking at the subclasses of - * --------------- - */ - if (inherited_result_rel) - { - JunkFilter *j = ExecInitJunkFilter(initNode->targetlist, - ExecGetTupType(initNode)); - - junkList = lappend(junkList, j); - } - } - appendstate->as_junkFilter_list = junkList; - if (junkList != NIL) - estate->es_junkFilter = (JunkFilter *) lfirst(junkList); /* ---------------- - * initialize the return type from the appropriate subplan. + * initialize tuple type * ---------------- */ - initNode = (Plan *) nth(0, appendplans); - ExecAssignResultType(&appendstate->cstate, ExecGetTupType(initNode)); + ExecAssignResultTypeFromTL((Plan *) node, &appendstate->cstate); appendstate->cstate.cs_ProjInfo = NULL; /* ---------------- @@ -357,10 +237,9 @@ int ExecCountSlotsAppend(Append *node) { List *plan; - List *appendplans = node->appendplans; int nSlots = 0; - foreach(plan, appendplans) + foreach(plan, node->appendplans) nSlots += ExecCountSlotsNode((Plan *) lfirst(plan)); return nSlots + APPEND_NSLOTS; } @@ -430,16 +309,14 @@ ExecProcAppend(Append *node) * direction and try processing again (recursively) * ---------------- */ - whichplan = appendstate->as_whichplan; - if (ScanDirectionIsForward(direction)) - appendstate->as_whichplan = whichplan + 1; + appendstate->as_whichplan++; else - appendstate->as_whichplan = whichplan - 1; + appendstate->as_whichplan--; /* ---------------- * return something from next node or an empty slot - * all of our subplans have been exhausted. + * if all of our subplans have been exhausted. * ---------------- */ if (exec_append_initialize_next(node)) @@ -469,7 +346,6 @@ ExecEndAppend(Append *node) List *appendplans; bool *initialized; int i; - List *resultRelationInfoList; /* ---------------- * get information from the node @@ -490,40 +366,8 @@ ExecEndAppend(Append *node) if (initialized[i]) ExecEndNode((Plan *) nth(i, appendplans), (Plan *) node); } - - /* ---------------- - * close out the different result relations - * - * NB: this must agree with what EndPlan() does to close a result rel - * ---------------- - */ - resultRelationInfoList = appendstate->as_result_relation_info_list; - while (resultRelationInfoList != NIL) - { - RelationInfo *resultRelationInfo; - - resultRelationInfo = (RelationInfo *) lfirst(resultRelationInfoList); - - heap_close(resultRelationInfo->ri_RelationDesc, NoLock); - /* close indices on the result relation, too */ - ExecCloseIndices(resultRelationInfo); - - /* - * estate may (or may not) be pointing at one of my result relations. - * If so, make sure EndPlan() doesn't try to close it again! - */ - if (estate->es_result_relation_info == resultRelationInfo) - estate->es_result_relation_info = NULL; - - pfree(resultRelationInfo); - resultRelationInfoList = lnext(resultRelationInfoList); - } - appendstate->as_result_relation_info_list = NIL; - - /* - * XXX should free appendstate->as_junkfilter_list here - */ } + void ExecReScanAppend(Append *node, ExprContext *exprCtxt, Plan *parent) { diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index b953dcd3697..56ba1375feb 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.24 2000/07/12 02:37:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.25 2000/11/12 00:36:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -156,7 +156,6 @@ InitScanRelation(SeqScan *node, EState *estate, ScanDirection direction; Relation currentRelation; HeapScanDesc currentScanDesc; - RelationInfo *resultRelationInfo; /* ---------------- * get the relation object id from the relid'th entry @@ -169,7 +168,6 @@ InitScanRelation(SeqScan *node, EState *estate, rtentry = rt_fetch(relid, rangeTable); reloid = rtentry->relid; direction = estate->es_direction; - resultRelationInfo = estate->es_result_relation_info; ExecOpenScanR(reloid, /* relation */ 0, /* nkeys */ |