From 31b255318ded2547a9dbc0425768e9bb14427aaa Mon Sep 17 00:00:00 2001 From: Mitsuru Hasegawa Date: Wed, 8 Aug 2012 20:27:44 +0900 Subject: [PATCH] =?utf8?q?Bug=20fix:EXECUTE=E3=82=B3=E3=83=9E=E3=83=B3?= =?utf8?q?=E3=83=89=E4=B8=AD=E3=81=AB=E3=82=A8=E3=83=A9=E3=83=BC=E7=B5=82?= =?utf8?q?=E4=BA=86=E3=81=97=E3=81=9F=E3=81=82=E3=81=A8=E3=81=ABSELECT?= =?utf8?q?=E3=82=92=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B=E3=81=A8=20?= =?utf8?q?=E6=83=B3=E5=AE=9A=E5=A4=96=E3=81=AE=E5=AE=9F=E8=A1=8C=E8=A8=88?= =?utf8?q?=E7=94=BB=E3=81=AB=E3=81=AA=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92?= =?utf8?q?=E4=BF=AE=E6=AD=A3=E3=81=97=E3=81=9F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit EXECUTEコマンド実行時に、ProcessUtility_hookの初期処理で外部変数に ステートメント名を保存し、終了処理でNULLに戻すが、ProcessUtility_hook の実行中にエラー終了した場合は、外部変数にステートメント名が設定 されたままだった。 このため、その後SELECT等の通常のクエリを発行すると、外部変数に 残っているステートメント名を使用して、プランキャッシュからクエリ 文字列を取得し、その文字列に指定されているヒントを使用していた。 --- Makefile | 4 ++++ expected/prepare-9.1.out | 18 ++++++++++++++++++ expected/prepare-9.2.out | 18 ++++++++++++++++++ pg_hint_plan.c | 16 ++++++++++++++++ sql/prepare.sql | 2 ++ 5 files changed, 58 insertions(+) diff --git a/Makefile b/Makefile index 81080cd..c342956 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,10 @@ MODULES = pg_hint_plan REGRESS = init base_plan pg_hint_plan prepare fdw +ifdef UNIT_TEST +PG_CPPFLAGS = -O0 +endif + EXTRA_CLEAN = sql/fdw.sql expected/base_plan.out expected/prepare.out expected/fdw.out PG_CONFIG = pg_config diff --git a/expected/prepare-9.1.out b/expected/prepare-9.1.out index 66fb6ab..08e095d 100644 --- a/expected/prepare-9.1.out +++ b/expected/prepare-9.1.out @@ -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) + diff --git a/expected/prepare-9.2.out b/expected/prepare-9.2.out index ed55e2a..62f25b4 100644 --- a/expected/prepare-9.2.out +++ b/expected/prepare-9.2.out @@ -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) + diff --git a/pg_hint_plan.c b/pg_hint_plan.c index fd8743a..5ae0c30 100644 --- a/pg_hint_plan.c +++ b/pg_hint_plan.c @@ -1384,11 +1384,18 @@ set_join_config_options(unsigned char enforce_mask, GucContext context) */ static void +ProcessUtility_hook_error_callback(void *arg) +{ + stmt_name = NULL; +} + +static void pg_hint_plan_ProcessUtility(Node *parsetree, const char *queryString, ParamListInfo params, bool isTopLevel, DestReceiver *dest, char *completionTag) { Node *node; + ErrorContextCallback errcontext; if (!pg_hint_plan_enable) { @@ -1428,6 +1435,12 @@ pg_hint_plan_ProcessUtility(Node *parsetree, const char *queryString, { ExecuteStmt *stmt; + /* Set up callback to statement name reset. */ + errcontext.callback = ProcessUtility_hook_error_callback; + errcontext.arg = NULL; + errcontext.previous = error_context_stack; + error_context_stack = &errcontext; + stmt = (ExecuteStmt *) node; stmt_name = stmt->name; } @@ -1442,6 +1455,9 @@ pg_hint_plan_ProcessUtility(Node *parsetree, const char *queryString, if (stmt_name) { stmt_name = NULL; + + /* Remove error callback. */ + error_context_stack = errcontext.previous; } } diff --git a/sql/prepare.sql b/sql/prepare.sql index 26d69a3..e10d776 100644 --- a/sql/prepare.sql +++ b/sql/prepare.sql @@ -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; -- 2.11.0