|
35 | 35 | * Portions Copyright (c) 1994, Regents of the University of California
|
36 | 36 | *
|
37 | 37 | * IDENTIFICATION
|
38 |
| - * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.32 2010/01/02 16:57:55 momjian Exp $ |
| 38 | + * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.33 2010/01/13 16:56:56 tgl Exp $ |
39 | 39 | *
|
40 | 40 | *-------------------------------------------------------------------------
|
41 | 41 | */
|
@@ -1068,14 +1068,57 @@ PlanCacheSysCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
|
1068 | 1068 | void
|
1069 | 1069 | ResetPlanCache(void)
|
1070 | 1070 | {
|
1071 |
| - ListCell *lc; |
| 1071 | + ListCell *lc1; |
1072 | 1072 |
|
1073 |
| - foreach(lc, cached_plans_list) |
| 1073 | + foreach(lc1, cached_plans_list) |
1074 | 1074 | {
|
1075 |
| - CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc); |
| 1075 | + CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc1); |
1076 | 1076 | CachedPlan *plan = plansource->plan;
|
| 1077 | + ListCell *lc2; |
1077 | 1078 |
|
1078 |
| - if (plan) |
1079 |
| - plan->dead = true; |
| 1079 | + /* No work if it's already invalidated */ |
| 1080 | + if (!plan || plan->dead) |
| 1081 | + continue; |
| 1082 | + |
| 1083 | + /* |
| 1084 | + * We *must not* mark transaction control statements as dead, |
| 1085 | + * particularly not ROLLBACK, because they may need to be executed in |
| 1086 | + * aborted transactions when we can't revalidate them (cf bug #5269). |
| 1087 | + * In general there is no point in invalidating utility statements |
| 1088 | + * since they have no plans anyway. So mark it dead only if it |
| 1089 | + * contains at least one non-utility statement. |
| 1090 | + */ |
| 1091 | + if (plan->fully_planned) |
| 1092 | + { |
| 1093 | + /* Search statement list for non-utility statements */ |
| 1094 | + foreach(lc2, plan->stmt_list) |
| 1095 | + { |
| 1096 | + PlannedStmt *plannedstmt = (PlannedStmt *) lfirst(lc2); |
| 1097 | + |
| 1098 | + Assert(!IsA(plannedstmt, Query)); |
| 1099 | + if (IsA(plannedstmt, PlannedStmt)) |
| 1100 | + { |
| 1101 | + /* non-utility statement, so invalidate */ |
| 1102 | + plan->dead = true; |
| 1103 | + break; /* out of stmt_list scan */ |
| 1104 | + } |
| 1105 | + } |
| 1106 | + } |
| 1107 | + else |
| 1108 | + { |
| 1109 | + /* Search Query list for non-utility statements */ |
| 1110 | + foreach(lc2, plan->stmt_list) |
| 1111 | + { |
| 1112 | + Query *query = (Query *) lfirst(lc2); |
| 1113 | + |
| 1114 | + Assert(IsA(query, Query)); |
| 1115 | + if (query->commandType != CMD_UTILITY) |
| 1116 | + { |
| 1117 | + /* non-utility statement, so invalidate */ |
| 1118 | + plan->dead = true; |
| 1119 | + break; /* out of stmt_list scan */ |
| 1120 | + } |
| 1121 | + } |
| 1122 | + } |
1080 | 1123 | }
|
1081 | 1124 | }
|
0 commit comments