OSDN Git Service

Bug fix:EXECUTEコマンド中にエラー終了したあとにSELECTを実行すると
authorMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Thu, 9 Aug 2012 09:19:40 +0000 (18:19 +0900)
committerMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Thu, 9 Aug 2012 09:19:40 +0000 (18:19 +0900)
想定外の実行計画になる問題を修正した。

EXECUTEコマンド実行時に、ProcessUtility_hookの初期処理で外部変数に
ステートメント名を保存し、終了処理でNULLに戻すが、ProcessUtility_hook
の実行中にエラー終了した場合は、外部変数にステートメント名が設定
されたままだった。
このため、その後SELECT等の通常のクエリを発行すると、外部変数に
残っているステートメント名を使用して、プランキャッシュからクエリ
文字列を取得し、その文字列に指定されているヒントを使用していた。

expected/prepare-9.1.out
expected/prepare-9.2.out
pg_hint_plan.c
sql/prepare.sql

index 66fb6ab..08e095d 100644 (file)
@@ -653,3 +653,21 @@ EXPLAIN (COSTS false) EXECUTE p7 (10);
 /*+ NestLoop(t1 t2) */
 EXPLAIN (COSTS false) EXECUTE p8 (10);
 ERROR:  prepared statement "p8" does not exist
+/*+ NestLoop(t1 t2) */
+EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > 10;
+LOG:  pg_hint_plan:
+used hint:
+NestLoop(t1 t2)
+not used hint:
+duplication hint:
+error hint:
+
+                       QUERY PLAN                       
+--------------------------------------------------------
+ Aggregate
+   ->  Nested Loop
+         ->  Seq Scan on t2
+         ->  Index Scan using t1_pkey on t1
+               Index Cond: ((id > 10) AND (id = t2.id))
+(5 rows)
+
index ed55e2a..62f25b4 100644 (file)
@@ -818,3 +818,21 @@ EXPLAIN (COSTS false) EXECUTE p7 (10);
 /*+ NestLoop(t1 t2) */
 EXPLAIN (COSTS false) EXECUTE p8 (10);
 ERROR:  prepared statement "p8" does not exist
+/*+ NestLoop(t1 t2) */
+EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > 10;
+LOG:  pg_hint_plan:
+used hint:
+NestLoop(t1 t2)
+not used hint:
+duplication hint:
+error hint:
+
+                       QUERY PLAN                       
+--------------------------------------------------------
+ Aggregate
+   ->  Nested Loop
+         ->  Seq Scan on t2
+         ->  Index Scan using t1_pkey on t1
+               Index Cond: ((id > 10) AND (id = t2.id))
+(5 rows)
+
index fd8743a..0989fdf 100644 (file)
@@ -1432,17 +1432,35 @@ pg_hint_plan_ProcessUtility(Node *parsetree, const char *queryString,
                stmt_name = stmt->name;
        }
 
+       if (stmt_name)
+       {
+               PG_TRY();
+               {
+                       if (prev_ProcessUtility)
+                               (*prev_ProcessUtility) (parsetree, queryString, params,
+                                                                               isTopLevel, dest, completionTag);
+                       else
+                               standard_ProcessUtility(parsetree, queryString, params,
+                                                                               isTopLevel, dest, completionTag);
+               }
+               PG_CATCH();
+               {
+                       stmt_name = NULL;
+                       PG_RE_THROW();
+               }
+               PG_END_TRY();
+
+               stmt_name = NULL;
+
+               return;
+       }
+
        if (prev_ProcessUtility)
                (*prev_ProcessUtility) (parsetree, queryString, params,
                                                                isTopLevel, dest, completionTag);
        else
                standard_ProcessUtility(parsetree, queryString, params,
                                                                isTopLevel, dest, completionTag);
-
-       if (stmt_name)
-       {
-               stmt_name = NULL;
-       }
 }
 
 static PlannedStmt *
index 26d69a3..e10d776 100644 (file)
@@ -127,3 +127,5 @@ EXPLAIN (COSTS false) EXECUTE p7 (10);
 -- error case
 /*+ NestLoop(t1 t2) */
 EXPLAIN (COSTS false) EXECUTE p8 (10);
+/*+ NestLoop(t1 t2) */
+EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > 10;