diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/explain.c | 32 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 32 |
2 files changed, 52 insertions, 12 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index ef3d9beb062..048d12f97a2 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.190 2009/08/22 02:06:32 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.191 2009/10/10 01:43:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -581,6 +581,7 @@ ExplainNode(Plan *plan, PlanState *planstate, const char *pname; /* node type name for text output */ const char *sname; /* node type name for non-text output */ const char *strategy = NULL; + const char *operation = NULL; int save_indent = es->indent; bool haschildren; @@ -591,6 +592,24 @@ ExplainNode(Plan *plan, PlanState *planstate, case T_Result: pname = sname = "Result"; break; + case T_ModifyTable: + sname = "ModifyTable"; + switch (((ModifyTable *) plan)->operation) + { + case CMD_INSERT: + pname = operation = "Insert"; + break; + case CMD_UPDATE: + pname = operation = "Update"; + break; + case CMD_DELETE: + pname = operation = "Delete"; + break; + default: + pname = "???"; + break; + } + break; case T_Append: pname = sname = "Append"; break; @@ -736,6 +755,8 @@ ExplainNode(Plan *plan, PlanState *planstate, ExplainPropertyText("Node Type", sname, es); if (strategy) ExplainPropertyText("Strategy", strategy, es); + if (operation) + ExplainPropertyText("Operation", operation, es); if (relationship) ExplainPropertyText("Parent Relationship", relationship, es); if (plan_name) @@ -1023,6 +1044,7 @@ ExplainNode(Plan *plan, PlanState *planstate, haschildren = plan->initPlan || outerPlan(plan) || innerPlan(plan) || + IsA(plan, ModifyTable) || IsA(plan, Append) || IsA(plan, BitmapAnd) || IsA(plan, BitmapOr) || @@ -1059,6 +1081,11 @@ ExplainNode(Plan *plan, PlanState *planstate, /* special child plans */ switch (nodeTag(plan)) { + case T_ModifyTable: + ExplainMemberNodes(((ModifyTable *) plan)->plans, + ((ModifyTableState *) planstate)->mt_plans, + outer_plan, es); + break; case T_Append: ExplainMemberNodes(((Append *) plan)->appendplans, ((AppendState *) planstate)->appendplans, @@ -1408,7 +1435,8 @@ ExplainScanTarget(Scan *plan, ExplainState *es) } /* - * Explain the constituent plans of an Append, BitmapAnd, or BitmapOr node. + * Explain the constituent plans of a ModifyTable, Append, BitmapAnd, + * or BitmapOr node. * * Ordinarily we don't pass down outer_plan to our child nodes, but in these * cases we must, since the node could be an "inner indexscan" in which case diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index c1f55cfcf93..47cf0c470d6 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.252 2009/08/04 16:08:36 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.253 2009/10/10 01:43:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -55,6 +55,7 @@ int SessionReplicationRole = SESSION_REPLICATION_ROLE_ORIGIN; static void ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid); static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx); static HeapTuple GetTupleForTrigger(EState *estate, + PlanState *subplanstate, ResultRelInfo *relinfo, ItemPointer tid, TupleTableSlot **newSlot); @@ -1793,7 +1794,8 @@ ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo) } bool -ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, +ExecBRDeleteTriggers(EState *estate, PlanState *subplanstate, + ResultRelInfo *relinfo, ItemPointer tupleid) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; @@ -1806,7 +1808,8 @@ ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *newSlot; int i; - trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, &newSlot); + trigtuple = GetTupleForTrigger(estate, subplanstate, relinfo, tupleid, + &newSlot); if (trigtuple == NULL) return false; @@ -1862,7 +1865,7 @@ ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) { - HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo, + HeapTuple trigtuple = GetTupleForTrigger(estate, NULL, relinfo, tupleid, NULL); AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE, @@ -1941,7 +1944,8 @@ ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo) } HeapTuple -ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, +ExecBRUpdateTriggers(EState *estate, PlanState *subplanstate, + ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple newtuple) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; @@ -1954,16 +1958,18 @@ ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *newSlot; int i; - trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, &newSlot); + trigtuple = GetTupleForTrigger(estate, subplanstate, relinfo, tupleid, + &newSlot); if (trigtuple == NULL) return NULL; /* * In READ COMMITTED isolation level it's possible that newtuple was - * changed due to concurrent update. + * changed due to concurrent update. In that case we have a raw subplan + * output tuple and need to run it through the junk filter. */ if (newSlot != NULL) - intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot); + intuple = newtuple = ExecRemoveJunk(relinfo->ri_junkFilter, newSlot); LocTriggerData.type = T_TriggerData; LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE | @@ -2014,7 +2020,7 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0) { - HeapTuple trigtuple = GetTupleForTrigger(estate, relinfo, + HeapTuple trigtuple = GetTupleForTrigger(estate, NULL, relinfo, tupleid, NULL); AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE, @@ -2094,7 +2100,9 @@ ExecASTruncateTriggers(EState *estate, ResultRelInfo *relinfo) static HeapTuple -GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo, +GetTupleForTrigger(EState *estate, + PlanState *subplanstate, + ResultRelInfo *relinfo, ItemPointer tid, TupleTableSlot **newSlot) { @@ -2111,6 +2119,9 @@ GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo, *newSlot = NULL; + /* caller must pass a subplanstate if EvalPlanQual is possible */ + Assert(subplanstate != NULL); + /* * lock tuple for update */ @@ -2143,6 +2154,7 @@ ltrmark:; epqslot = EvalPlanQual(estate, relinfo->ri_RangeTableIndex, + subplanstate, &update_ctid, update_xmax); if (!TupIsNull(epqslot)) |