OSDN Git Service
(root)
/
pghintplan
/
pg_hint_plan.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Correctly handle planner nesting
[pghintplan/pg_hint_plan.git]
/
pg_hint_plan.c
diff --git
a/pg_hint_plan.c
b/pg_hint_plan.c
index
e050672
..
c6cd055
100644
(file)
--- a/
pg_hint_plan.c
+++ b/
pg_hint_plan.c
@@
-3,13
+3,16
@@
* pg_hint_plan.c
* hinting on how to execute a query for PostgreSQL
*
* pg_hint_plan.c
* hinting on how to execute a query for PostgreSQL
*
- * Copyright (c) 2012-201
8
, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ * Copyright (c) 2012-201
9
, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
+#include "access/genam.h"
+#include "access/heapam.h"
+#include "access/relation.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_index.h"
#include "commands/prepare.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_index.h"
#include "commands/prepare.h"
@@
-17,11
+20,12
@@
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "nodes/params.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "nodes/params.h"
-#include "
nodes/relation
.h"
+#include "
optimizer/appendinfo
.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/geqo.h"
#include "optimizer/joininfo.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/geqo.h"
#include "optimizer/joininfo.h"
+#include "optimizer/optimizer.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "optimizer/plancat.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "optimizer/plancat.h"
@@
-512,6
+516,7
@@
static int pg_hint_plan_debug_message_level = LOG;
static bool pg_hint_plan_enable_hint_table = false;
static int plpgsql_recurse_level = 0; /* PLpgSQL recursion level */
static bool pg_hint_plan_enable_hint_table = false;
static int plpgsql_recurse_level = 0; /* PLpgSQL recursion level */
+static int recurse_level = 0; /* recursion level incl. direct SPI calls */
static int hint_inhibit_level = 0; /* Inhibit hinting if this is above 0 */
/* (This could not be above 1) */
static int max_hint_nworkers = -1; /* Maximum nworkers of Workers hints */
static int hint_inhibit_level = 0; /* Inhibit hinting if this is above 0 */
/* (This could not be above 1) */
static int max_hint_nworkers = -1; /* Maximum nworkers of Workers hints */
@@
-2967,6
+2972,9
@@
pg_hint_plan_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
if (prev_ProcessUtility_hook)
prev_ProcessUtility_hook(pstmt, queryString, context, params, queryEnv,
dest, completionTag);
if (prev_ProcessUtility_hook)
prev_ProcessUtility_hook(pstmt, queryString, context, params, queryEnv,
dest, completionTag);
+ else
+ standard_ProcessUtility(pstmt, queryString, context, params, queryEnv,
+ dest, completionTag);
if (plpgsql_recurse_level == 0)
current_hint_retrieved = false;
if (plpgsql_recurse_level == 0)
current_hint_retrieved = false;
@@
-2981,6
+2989,7
@@
pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
int save_nestlevel;
PlannedStmt *result;
HintState *hstate;
int save_nestlevel;
PlannedStmt *result;
HintState *hstate;
+ const char *prev_hint_str;
/*
* Use standard planner if pg_hint_plan is disabled or current nesting
/*
* Use standard planner if pg_hint_plan is disabled or current nesting
@@
-3009,9
+3018,6
@@
pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
{
MemoryContext oldcontext;
{
MemoryContext oldcontext;
- if (current_hint_str)
- pfree((void *)current_hint_str);
-
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
current_hint_str =
get_hints_from_comment((char *)error_context_stack->arg);
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
current_hint_str =
get_hints_from_comment((char *)error_context_stack->arg);
@@
-3081,10
+3087,21
@@
pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
*/
PG_TRY();
{
*/
PG_TRY();
{
+ /*
+ * The planner call below may replace current_hint_str. Store and
+ * restore it so that the subsequent planning in the upper level
+ * doesn't get confused.
+ */
+ recurse_level++;
+ prev_hint_str = current_hint_str;
+
if (prev_planner)
result = (*prev_planner) (parse, cursorOptions, boundParams);
else
result = standard_planner(parse, cursorOptions, boundParams);
if (prev_planner)
result = (*prev_planner) (parse, cursorOptions, boundParams);
else
result = standard_planner(parse, cursorOptions, boundParams);
+
+ current_hint_str = prev_hint_str;
+ recurse_level--;
}
PG_CATCH();
{
}
PG_CATCH();
{
@@
-3092,6
+3109,8
@@
pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* Rollback changes of GUC parameters, and pop current hint context
* from hint stack to rewind the state.
*/
* Rollback changes of GUC parameters, and pop current hint context
* from hint stack to rewind the state.
*/
+ current_hint_str = prev_hint_str;
+ recurse_level--;
AtEOXact_GUC(true, save_nestlevel);
pop_hint();
PG_RE_THROW();
AtEOXact_GUC(true, save_nestlevel);
pop_hint();
PG_RE_THROW();
@@
-3102,7
+3121,7
@@
pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
/*
* current_hint_str is useless after planning of the top-level query.
*/
/*
* current_hint_str is useless after planning of the top-level query.
*/
- if (
plpgsql_
recurse_level < 1 && current_hint_str)
+ if (recurse_level < 1 && current_hint_str)
{
pfree((void *)current_hint_str);
current_hint_str = NULL;
{
pfree((void *)current_hint_str);
current_hint_str = NULL;
@@
-4717,7
+4736,8
@@
pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel,
}
/* Generate gather paths */
}
/* Generate gather paths */
- if (rel->reloptkind == RELOPT_BASEREL)
+ if (rel->reloptkind == RELOPT_BASEREL &&
+ bms_membership(root->all_baserels) != BMS_SINGLETON)
generate_gather_paths(root, rel, false);
}
}
generate_gather_paths(root, rel, false);
}
}