Assorted contrib infrastructures patch
Hello,
I'm submitting 2 contrib modules and there 3 patches to core for them
from me and Martin, but they confict each other and there are some hunks
and rejections already. Here is an assorted patch of them.
Can I ask you to review the patches in this form?
- Martin's querydesc patch
http://archives.postgresql.org/message-id/490A00A8.7050708@gmail.com
- My patch for contrib/auto_explain
http://archives.postgresql.org/message-id/20081009165157.9BE4.52131E4D@oss.ntt.co.jp
- My patch for contrib/pg_stat_statements
http://archives.postgresql.org/message-id/20081027171917.ADD6.52131E4D@oss.ntt.co.jp
This is a list of modification by the patch:
- Add sourceText field in QueryDesc.
To handle query texts of nested statements in ExecutorRun_hook.
- Add DefineCustomVariable(type, variable) function.
New API to define a custom guc variable to open
config_group and flags to developers.
- Add ExplainOnePlan(outStr, queryDesc, ...) function.
Enable access to EXPLAIN output by plugin modules.
- Add force_instrument variable.
If the value is true, executor states are always initialized
with instruments. Used by auto_explain.
- Add startup_hook.
Called on server startup by startup process
where LoadFreeSpaceMap() in 8.3 had been called.
- Add shutdown_hook.
Called on server shutdown by bgwriter
where DumpFreeSpaceMap() in 8.3 had been called.
- shared_preload_libraries are loaded by auxiliary processes.
Windows port requires it.
Regards,
---
ITAGAKI Takahiro
NTT Open Source Software Center
Attachments:
contrib_infrastructures.patchapplication/octet-stream; name=contrib_infrastructures.patchDownload
diff -cpr HEAD/src/backend/bootstrap/bootstrap.c contrib_infrastructures/src/backend/bootstrap/bootstrap.c
*** HEAD/src/backend/bootstrap/bootstrap.c Sun Nov 2 10:45:27 2008
--- contrib_infrastructures/src/backend/bootstrap/bootstrap.c Thu Nov 6 17:06:36 2008
*************** typedef struct _IndexList
*** 193,198 ****
--- 193,199 ----
static IndexList *ILHead = NULL;
+ startup_hook_type startup_hook = NULL;
/*
* AuxiliaryProcessMain
*************** AuxiliaryProcessMain(int argc, char *arg
*** 419,424 ****
--- 420,427 ----
bootstrap_signals();
StartupXLOG();
BuildFlatFiles(false);
+ if (startup_hook)
+ startup_hook();
proc_exit(0); /* startup done */
case BgWriterProcess:
diff -cpr HEAD/src/backend/commands/copy.c contrib_infrastructures/src/backend/commands/copy.c
*** HEAD/src/backend/commands/copy.c Sun Nov 2 10:45:27 2008
--- contrib_infrastructures/src/backend/commands/copy.c Thu Nov 6 17:06:36 2008
*************** DoCopy(const CopyStmt *stmt, const char
*** 1056,1062 ****
/* Create a QueryDesc requesting no output */
cstate->queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(),
InvalidSnapshot,
! dest, NULL, false);
/*
* Call ExecutorStart to prepare the plan for execution.
--- 1056,1062 ----
/* Create a QueryDesc requesting no output */
cstate->queryDesc = CreateQueryDesc(plan, GetActiveSnapshot(),
InvalidSnapshot,
! dest, NULL, false, queryString);
/*
* Call ExecutorStart to prepare the plan for execution.
diff -cpr HEAD/src/backend/commands/explain.c contrib_infrastructures/src/backend/commands/explain.c
*** HEAD/src/backend/commands/explain.c Tue Oct 7 05:29:38 2008
--- contrib_infrastructures/src/backend/commands/explain.c Thu Nov 6 17:06:36 2008
*************** ExplainOneQuery(Query *query, ExplainStm
*** 172,178 ****
plan = pg_plan_query(query, 0, params);
/* run it (if needed) and produce output */
! ExplainOnePlan(plan, params, stmt, tstate);
}
}
--- 172,178 ----
plan = pg_plan_query(query, 0, params);
/* run it (if needed) and produce output */
! ExplainOnePlan(plan, params, stmt, tstate, queryString);
}
}
*************** ExplainOneUtility(Node *utilityStmt, Exp
*** 219,230 ****
*/
void
ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params,
! ExplainStmt *stmt, TupOutputState *tstate)
{
QueryDesc *queryDesc;
instr_time starttime;
double totaltime = 0;
- ExplainState *es;
StringInfoData buf;
int eflags;
--- 219,230 ----
*/
void
ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params,
! ExplainStmt *stmt, TupOutputState *tstate,
! const char *queryString)
{
QueryDesc *queryDesc;
instr_time starttime;
double totaltime = 0;
StringInfoData buf;
int eflags;
*************** ExplainOnePlan(PlannedStmt *plannedstmt,
*** 238,244 ****
queryDesc = CreateQueryDesc(plannedstmt,
GetActiveSnapshot(), InvalidSnapshot,
None_Receiver, params,
! stmt->analyze);
INSTR_TIME_SET_CURRENT(starttime);
--- 238,244 ----
queryDesc = CreateQueryDesc(plannedstmt,
GetActiveSnapshot(), InvalidSnapshot,
None_Receiver, params,
! stmt->analyze, queryString);
INSTR_TIME_SET_CURRENT(starttime);
*************** ExplainOnePlan(PlannedStmt *plannedstmt,
*** 265,281 ****
totaltime += elapsed_time(&starttime);
}
- es = (ExplainState *) palloc0(sizeof(ExplainState));
-
- es->printTList = stmt->verbose;
- es->printAnalyze = stmt->analyze;
- es->pstmt = queryDesc->plannedstmt;
- es->rtable = queryDesc->plannedstmt->rtable;
-
initStringInfo(&buf);
! explain_outNode(&buf,
! queryDesc->plannedstmt->planTree, queryDesc->planstate,
! NULL, 0, es);
/*
* If we ran the command, run any AFTER triggers it queued. (Note this
--- 265,272 ----
totaltime += elapsed_time(&starttime);
}
initStringInfo(&buf);
! ExplainOneResult(&buf, queryDesc, stmt->analyze, stmt->verbose);
/*
* If we ran the command, run any AFTER triggers it queued. (Note this
*************** ExplainOnePlan(PlannedStmt *plannedstmt,
*** 290,296 ****
}
/* Print info about runtime of triggers */
! if (es->printAnalyze)
{
ResultRelInfo *rInfo;
bool show_relname;
--- 281,287 ----
}
/* Print info about runtime of triggers */
! if (stmt->analyze)
{
ResultRelInfo *rInfo;
bool show_relname;
*************** ExplainOnePlan(PlannedStmt *plannedstmt,
*** 335,341 ****
do_text_output_multiline(tstate, buf.data);
pfree(buf.data);
! pfree(es);
}
/*
--- 326,351 ----
do_text_output_multiline(tstate, buf.data);
pfree(buf.data);
! }
!
! /*
! * ExplainOneResult -
! * converts a Plan node into ascii string and appends it to 'str'
! */
! void
! ExplainOneResult(StringInfo str, QueryDesc *queryDesc,
! bool analyze, bool verbose)
! {
! ExplainState es = { 0 };
!
! es.printTList = verbose;
! es.printAnalyze = analyze;
! es.pstmt = queryDesc->plannedstmt;
! es.rtable = queryDesc->plannedstmt->rtable;
!
! explain_outNode(str,
! queryDesc->plannedstmt->planTree, queryDesc->planstate,
! NULL, 0, &es);
}
/*
diff -cpr HEAD/src/backend/commands/prepare.c contrib_infrastructures/src/backend/commands/prepare.c
*** HEAD/src/backend/commands/prepare.c Wed Oct 29 09:00:38 2008
--- contrib_infrastructures/src/backend/commands/prepare.c Thu Nov 6 17:06:36 2008
*************** ExplainExecuteQuery(ExecuteStmt *execstm
*** 697,703 ****
pstmt->intoClause = execstmt->into;
}
! ExplainOnePlan(pstmt, paramLI, stmt, tstate);
}
else
{
--- 697,703 ----
pstmt->intoClause = execstmt->into;
}
! ExplainOnePlan(pstmt, paramLI, stmt, tstate, queryString);
}
else
{
diff -cpr HEAD/src/backend/executor/functions.c contrib_infrastructures/src/backend/executor/functions.c
*** HEAD/src/backend/executor/functions.c Sat Nov 1 06:07:55 2008
--- contrib_infrastructures/src/backend/executor/functions.c Thu Nov 6 17:06:36 2008
*************** postquel_start(execution_state *es, SQLF
*** 413,424 ****
es->qd = CreateQueryDesc((PlannedStmt *) es->stmt,
snapshot, InvalidSnapshot,
dest,
! fcache->paramLI, false);
else
es->qd = CreateUtilityQueryDesc(es->stmt,
snapshot,
dest,
! fcache->paramLI);
/* We assume we don't need to set up ActiveSnapshot for ExecutorStart */
--- 413,424 ----
es->qd = CreateQueryDesc((PlannedStmt *) es->stmt,
snapshot, InvalidSnapshot,
dest,
! fcache->paramLI, false, fcache->src);
else
es->qd = CreateUtilityQueryDesc(es->stmt,
snapshot,
dest,
! fcache->paramLI, fcache->src);
/* We assume we don't need to set up ActiveSnapshot for ExecutorStart */
diff -cpr HEAD/src/backend/executor/spi.c contrib_infrastructures/src/backend/executor/spi.c
*** HEAD/src/backend/executor/spi.c Sun Nov 2 10:45:28 2008
--- contrib_infrastructures/src/backend/executor/spi.c Thu Nov 6 17:06:36 2008
*************** _SPI_execute_plan(SPIPlanPtr plan, Param
*** 1795,1801 ****
qdesc = CreateQueryDesc((PlannedStmt *) stmt,
snap, crosscheck_snapshot,
dest,
! paramLI, false);
res = _SPI_pquery(qdesc, fire_triggers,
canSetTag ? tcount : 0);
FreeQueryDesc(qdesc);
--- 1795,1802 ----
qdesc = CreateQueryDesc((PlannedStmt *) stmt,
snap, crosscheck_snapshot,
dest,
! paramLI, false,
! plansource->query_string);
res = _SPI_pquery(qdesc, fire_triggers,
canSetTag ? tcount : 0);
FreeQueryDesc(qdesc);
diff -cpr HEAD/src/backend/postmaster/bgwriter.c contrib_infrastructures/src/backend/postmaster/bgwriter.c
*** HEAD/src/backend/postmaster/bgwriter.c Tue Oct 14 17:06:39 2008
--- contrib_infrastructures/src/backend/postmaster/bgwriter.c Thu Nov 6 17:06:36 2008
*************** static BgWriterShmemStruct *BgWriterShme
*** 141,146 ****
--- 141,148 ----
/* interval for calling AbsorbFsyncRequests in CheckpointWriteDelay */
#define WRITES_PER_ABSORB 1000
+ shutdown_hook_type shutdown_hook = NULL;
+
/*
* GUC parameters
*/
*************** BackgroundWriterMain(void)
*** 396,401 ****
--- 398,405 ----
*/
ExitOnAnyError = true;
/* Close down the database */
+ if (shutdown_hook)
+ shutdown_hook();
ShutdownXLOG(0, 0);
/* Normal exit from the bgwriter is here */
proc_exit(0); /* done */
diff -cpr HEAD/src/backend/storage/lmgr/proc.c contrib_infrastructures/src/backend/storage/lmgr/proc.c
*** HEAD/src/backend/storage/lmgr/proc.c Mon Nov 3 06:24:52 2008
--- contrib_infrastructures/src/backend/storage/lmgr/proc.c Thu Nov 6 17:06:36 2008
*************** InitAuxiliaryProcess(void)
*** 381,386 ****
--- 381,390 ----
if (MyProc != NULL)
elog(ERROR, "you already exist");
+ #ifdef EXEC_BACKEND
+ process_shared_preload_libraries();
+ #endif
+
/*
* We use the ProcStructLock to protect assignment and releasing of
* AuxiliaryProcs entries.
diff -cpr HEAD/src/backend/tcop/pquery.c contrib_infrastructures/src/backend/tcop/pquery.c
*** HEAD/src/backend/tcop/pquery.c Fri Aug 1 22:16:09 2008
--- contrib_infrastructures/src/backend/tcop/pquery.c Thu Nov 6 17:06:36 2008
***************
*** 32,43 ****
* if there are several).
*/
Portal ActivePortal = NULL;
!
static void ProcessQuery(PlannedStmt *plan,
ParamListInfo params,
DestReceiver *dest,
! char *completionTag);
static void FillPortalStore(Portal portal, bool isTopLevel);
static uint32 RunFromStore(Portal portal, ScanDirection direction, long count,
DestReceiver *dest);
--- 32,44 ----
* if there are several).
*/
Portal ActivePortal = NULL;
! bool force_instrument = false;
static void ProcessQuery(PlannedStmt *plan,
ParamListInfo params,
DestReceiver *dest,
! char *completionTag,
! const char *sourceText);
static void FillPortalStore(Portal portal, bool isTopLevel);
static uint32 RunFromStore(Portal portal, ScanDirection direction, long count,
DestReceiver *dest);
*************** CreateQueryDesc(PlannedStmt *plannedstmt
*** 64,70 ****
Snapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
! bool doInstrument)
{
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
--- 65,72 ----
Snapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
! bool doInstrument,
! const char *sourceText)
{
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
*************** CreateQueryDesc(PlannedStmt *plannedstmt
*** 76,82 ****
qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
qd->dest = dest; /* output dest */
qd->params = params; /* parameter values passed into query */
! qd->doInstrument = doInstrument; /* instrumentation wanted? */
/* null these fields until set by ExecutorStart */
qd->tupDesc = NULL;
--- 78,85 ----
qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
qd->dest = dest; /* output dest */
qd->params = params; /* parameter values passed into query */
! qd->doInstrument = force_instrument || doInstrument; /* instrumentation wanted? */
! qd->sourceText = sourceText;
/* null these fields until set by ExecutorStart */
qd->tupDesc = NULL;
*************** QueryDesc *
*** 93,99 ****
CreateUtilityQueryDesc(Node *utilitystmt,
Snapshot snapshot,
DestReceiver *dest,
! ParamListInfo params)
{
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
--- 96,103 ----
CreateUtilityQueryDesc(Node *utilitystmt,
Snapshot snapshot,
DestReceiver *dest,
! ParamListInfo params,
! const char *sourceText)
{
QueryDesc *qd = (QueryDesc *) palloc(sizeof(QueryDesc));
*************** CreateUtilityQueryDesc(Node *utilitystmt
*** 105,110 ****
--- 109,115 ----
qd->dest = dest; /* output dest */
qd->params = params; /* parameter values passed into query */
qd->doInstrument = false; /* uninteresting for utilities */
+ qd->sourceText = sourceText;
/* null these fields until set by ExecutorStart */
qd->tupDesc = NULL;
*************** static void
*** 152,158 ****
ProcessQuery(PlannedStmt *plan,
ParamListInfo params,
DestReceiver *dest,
! char *completionTag)
{
QueryDesc *queryDesc;
--- 157,164 ----
ProcessQuery(PlannedStmt *plan,
ParamListInfo params,
DestReceiver *dest,
! char *completionTag,
! const char *sourceText)
{
QueryDesc *queryDesc;
*************** ProcessQuery(PlannedStmt *plan,
*** 168,174 ****
*/
queryDesc = CreateQueryDesc(plan,
GetActiveSnapshot(), InvalidSnapshot,
! dest, params, false);
/*
* Set up to collect AFTER triggers
--- 174,180 ----
*/
queryDesc = CreateQueryDesc(plan,
GetActiveSnapshot(), InvalidSnapshot,
! dest, params, false, sourceText);
/*
* Set up to collect AFTER triggers
*************** PortalStart(Portal portal, ParamListInfo
*** 504,510 ****
InvalidSnapshot,
None_Receiver,
params,
! false);
/*
* We do *not* call AfterTriggerBeginQuery() here. We assume
--- 510,517 ----
InvalidSnapshot,
None_Receiver,
params,
! false,
! portal->sourceText);
/*
* We do *not* call AfterTriggerBeginQuery() here. We assume
*************** PortalRunMulti(Portal portal, bool isTop
*** 1252,1265 ****
/* statement can set tag string */
ProcessQuery(pstmt,
portal->portalParams,
! dest, completionTag);
}
else
{
/* stmt added by rewrite cannot set tag */
ProcessQuery(pstmt,
portal->portalParams,
! altdest, NULL);
}
if (log_executor_stats)
--- 1259,1272 ----
/* statement can set tag string */
ProcessQuery(pstmt,
portal->portalParams,
! dest, completionTag, portal->sourceText);
}
else
{
/* stmt added by rewrite cannot set tag */
ProcessQuery(pstmt,
portal->portalParams,
! altdest, NULL, portal->sourceText);
}
if (log_executor_stats)
diff -cpr HEAD/src/backend/utils/misc/guc.c contrib_infrastructures/src/backend/utils/misc/guc.c
*** HEAD/src/backend/utils/misc/guc.c Mon Oct 6 22:05:36 2008
--- contrib_infrastructures/src/backend/utils/misc/guc.c Thu Nov 6 17:06:36 2008
*************** static const char *assign_pgstat_temp_di
*** 169,174 ****
--- 169,175 ----
static char *config_enum_get_options(struct config_enum *record,
const char *prefix, const char *suffix);
+ static void initialize_option(struct config_generic *gconf);
/*
*************** InitializeGUCOptions(void)
*** 3177,3288 ****
for (i = 0; i < num_guc_variables; i++)
{
struct config_generic *gconf = guc_variables[i];
!
! gconf->status = 0;
! gconf->reset_source = PGC_S_DEFAULT;
! gconf->source = PGC_S_DEFAULT;
! gconf->stack = NULL;
! gconf->sourcefile = NULL;
! gconf->sourceline = 0;
!
! switch (gconf->vartype)
! {
! case PGC_BOOL:
! {
! struct config_bool *conf = (struct config_bool *) gconf;
!
! if (conf->assign_hook)
! if (!(*conf->assign_hook) (conf->boot_val, true,
! PGC_S_DEFAULT))
! elog(FATAL, "failed to initialize %s to %d",
! conf->gen.name, (int) conf->boot_val);
! *conf->variable = conf->reset_val = conf->boot_val;
! break;
! }
! case PGC_INT:
! {
! struct config_int *conf = (struct config_int *) gconf;
!
! Assert(conf->boot_val >= conf->min);
! Assert(conf->boot_val <= conf->max);
! if (conf->assign_hook)
! if (!(*conf->assign_hook) (conf->boot_val, true,
! PGC_S_DEFAULT))
! elog(FATAL, "failed to initialize %s to %d",
! conf->gen.name, conf->boot_val);
! *conf->variable = conf->reset_val = conf->boot_val;
! break;
! }
! case PGC_REAL:
! {
! struct config_real *conf = (struct config_real *) gconf;
!
! Assert(conf->boot_val >= conf->min);
! Assert(conf->boot_val <= conf->max);
! if (conf->assign_hook)
! if (!(*conf->assign_hook) (conf->boot_val, true,
! PGC_S_DEFAULT))
! elog(FATAL, "failed to initialize %s to %g",
! conf->gen.name, conf->boot_val);
! *conf->variable = conf->reset_val = conf->boot_val;
! break;
! }
! case PGC_STRING:
! {
! struct config_string *conf = (struct config_string *) gconf;
! char *str;
!
! *conf->variable = NULL;
! conf->reset_val = NULL;
!
! if (conf->boot_val == NULL)
! {
! /* leave the value NULL, do not call assign hook */
! break;
! }
!
! str = guc_strdup(FATAL, conf->boot_val);
! conf->reset_val = str;
!
! if (conf->assign_hook)
! {
! const char *newstr;
!
! newstr = (*conf->assign_hook) (str, true,
! PGC_S_DEFAULT);
! if (newstr == NULL)
! {
! elog(FATAL, "failed to initialize %s to \"%s\"",
! conf->gen.name, str);
! }
! else if (newstr != str)
! {
! free(str);
!
! /*
! * See notes in set_config_option about casting
! */
! str = (char *) newstr;
! conf->reset_val = str;
! }
! }
! *conf->variable = str;
! break;
! }
! case PGC_ENUM:
! {
! struct config_enum *conf = (struct config_enum *) gconf;
!
! if (conf->assign_hook)
! if (!(*conf->assign_hook) (conf->boot_val, true,
! PGC_S_DEFAULT))
! elog(FATAL, "failed to initialize %s to %s",
! conf->gen.name,
! config_enum_lookup_by_value(conf, conf->boot_val));
! *conf->variable = conf->reset_val = conf->boot_val;
! break;
! }
! }
}
guc_dirty = false;
--- 3178,3184 ----
for (i = 0; i < num_guc_variables; i++)
{
struct config_generic *gconf = guc_variables[i];
! initialize_option(gconf);
}
guc_dirty = false;
*************** InitializeGUCOptions(void)
*** 3338,3343 ****
--- 3234,3348 ----
}
}
+ static void
+ initialize_option(struct config_generic *gconf)
+ {
+ gconf->status = 0;
+ gconf->reset_source = PGC_S_DEFAULT;
+ gconf->source = PGC_S_DEFAULT;
+ gconf->stack = NULL;
+ gconf->sourcefile = NULL;
+ gconf->sourceline = 0;
+
+ switch (gconf->vartype)
+ {
+ case PGC_BOOL:
+ {
+ struct config_bool *conf = (struct config_bool *) gconf;
+
+ if (conf->assign_hook)
+ if (!(*conf->assign_hook) (conf->boot_val, true,
+ PGC_S_DEFAULT))
+ elog(FATAL, "failed to initialize %s to %d",
+ conf->gen.name, (int) conf->boot_val);
+ *conf->variable = conf->reset_val = conf->boot_val;
+ break;
+ }
+ case PGC_INT:
+ {
+ struct config_int *conf = (struct config_int *) gconf;
+
+ Assert(conf->boot_val >= conf->min);
+ Assert(conf->boot_val <= conf->max);
+ if (conf->assign_hook)
+ if (!(*conf->assign_hook) (conf->boot_val, true,
+ PGC_S_DEFAULT))
+ elog(FATAL, "failed to initialize %s to %d",
+ conf->gen.name, conf->boot_val);
+ *conf->variable = conf->reset_val = conf->boot_val;
+ break;
+ }
+ case PGC_REAL:
+ {
+ struct config_real *conf = (struct config_real *) gconf;
+
+ Assert(conf->boot_val >= conf->min);
+ Assert(conf->boot_val <= conf->max);
+ if (conf->assign_hook)
+ if (!(*conf->assign_hook) (conf->boot_val, true,
+ PGC_S_DEFAULT))
+ elog(FATAL, "failed to initialize %s to %g",
+ conf->gen.name, conf->boot_val);
+ *conf->variable = conf->reset_val = conf->boot_val;
+ break;
+ }
+ case PGC_STRING:
+ {
+ struct config_string *conf = (struct config_string *) gconf;
+ char *str;
+
+ *conf->variable = NULL;
+ conf->reset_val = NULL;
+
+ if (conf->boot_val == NULL)
+ {
+ /* leave the value NULL, do not call assign hook */
+ break;
+ }
+
+ str = guc_strdup(FATAL, conf->boot_val);
+ conf->reset_val = str;
+
+ if (conf->assign_hook)
+ {
+ const char *newstr;
+
+ newstr = (*conf->assign_hook) (str, true,
+ PGC_S_DEFAULT);
+ if (newstr == NULL)
+ {
+ elog(FATAL, "failed to initialize %s to \"%s\"",
+ conf->gen.name, str);
+ }
+ else if (newstr != str)
+ {
+ free(str);
+
+ /*
+ * See notes in set_config_option about casting
+ */
+ str = (char *) newstr;
+ conf->reset_val = str;
+ }
+ }
+ *conf->variable = str;
+ break;
+ }
+ case PGC_ENUM:
+ {
+ struct config_enum *conf = (struct config_enum *) gconf;
+
+ if (conf->assign_hook)
+ if (!(*conf->assign_hook) (conf->boot_val, true,
+ PGC_S_DEFAULT))
+ elog(FATAL, "failed to initialize %s to %s",
+ conf->gen.name,
+ config_enum_lookup_by_value(conf, conf->boot_val));
+ *conf->variable = conf->reset_val = conf->boot_val;
+ break;
+ }
+ }
+ }
/*
* Select the configuration files and data directory to be used, and
*************** define_custom_variable(struct config_gen
*** 5639,5644 ****
--- 5644,5650 ----
if (res == NULL)
{
/* No placeholder to replace, so just add it */
+ initialize_option(variable);
add_guc_variable(variable, ERROR);
return;
}
*************** define_custom_variable(struct config_gen
*** 5673,5678 ****
--- 5679,5686 ----
set_config_option(name, value,
pHolder->gen.context, pHolder->gen.source,
GUC_ACTION_SET, true);
+ else
+ initialize_option(variable);
/*
* Free up as much as we conveniently can of the placeholder structure
*************** DefineCustomEnumVariable(const char *nam
*** 5804,5809 ****
--- 5812,5840 ----
var->assign_hook = assign_hook;
var->show_hook = show_hook;
define_custom_variable(&var->gen);
+ }
+
+ static const int config_varsize[] =
+ {
+ sizeof(struct config_bool),
+ sizeof(struct config_int),
+ sizeof(struct config_real),
+ sizeof(struct config_string),
+ sizeof(struct config_enum)
+ };
+
+ void
+ DefineCustomVariable(enum config_type type, const void *variable)
+ {
+ int size = config_varsize[type];
+ const struct config_generic *var = variable;
+ struct config_generic *gen;
+
+ gen = (struct config_generic *) guc_malloc(ERROR, size);
+ memcpy(gen, var, size);
+ gen->name = guc_strdup(ERROR, var->name);
+ gen->vartype = type;
+ define_custom_variable(gen);
}
void
diff -cpr HEAD/src/include/commands/explain.h contrib_infrastructures/src/include/commands/explain.h
*** HEAD/src/include/commands/explain.h Wed Jan 2 04:45:57 2008
--- contrib_infrastructures/src/include/commands/explain.h Thu Nov 6 17:06:36 2008
*************** extern void ExplainOneUtility(Node *util
*** 39,44 ****
TupOutputState *tstate);
extern void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params,
! ExplainStmt *stmt, TupOutputState *tstate);
#endif /* EXPLAIN_H */
--- 39,48 ----
TupOutputState *tstate);
extern void ExplainOnePlan(PlannedStmt *plannedstmt, ParamListInfo params,
! ExplainStmt *stmt, TupOutputState *tstate,
! const char *queryString);
!
! extern void ExplainOneResult(StringInfo str, QueryDesc *queryDesc,
! bool analyze, bool verbose);
#endif /* EXPLAIN_H */
diff -cpr HEAD/src/include/executor/execdesc.h contrib_infrastructures/src/include/executor/execdesc.h
*** HEAD/src/include/executor/execdesc.h Wed Jan 2 04:45:57 2008
--- contrib_infrastructures/src/include/executor/execdesc.h Thu Nov 6 17:06:36 2008
***************
*** 20,25 ****
--- 20,27 ----
#include "tcop/dest.h"
+ extern PGDLLIMPORT bool force_instrument;
+
/* ----------------
* query descriptor:
*
*************** typedef struct QueryDesc
*** 42,47 ****
--- 44,50 ----
DestReceiver *dest; /* the destination for tuple output */
ParamListInfo params; /* param values being passed in */
bool doInstrument; /* TRUE requests runtime instrumentation */
+ const char *sourceText; /* Source text for the query */
/* These fields are set by ExecutorStart */
TupleDesc tupDesc; /* descriptor for result tuples */
*************** extern QueryDesc *CreateQueryDesc(Planne
*** 55,66 ****
Snapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
! bool doInstrument);
extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt,
Snapshot snapshot,
DestReceiver *dest,
! ParamListInfo params);
extern void FreeQueryDesc(QueryDesc *qdesc);
--- 58,71 ----
Snapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
! bool doInstrument,
! const char *sourceText);
extern QueryDesc *CreateUtilityQueryDesc(Node *utilitystmt,
Snapshot snapshot,
DestReceiver *dest,
! ParamListInfo params,
! const char *sourceText);
extern void FreeQueryDesc(QueryDesc *qdesc);
diff -cpr HEAD/src/include/storage/ipc.h contrib_infrastructures/src/include/storage/ipc.h
*** HEAD/src/include/storage/ipc.h Thu Apr 17 08:59:40 2008
--- contrib_infrastructures/src/include/storage/ipc.h Thu Nov 6 17:06:36 2008
***************
*** 20,25 ****
--- 20,30 ----
typedef void (*pg_on_exit_callback) (int code, Datum arg);
+ typedef void (*startup_hook_type) (void);
+ extern PGDLLIMPORT startup_hook_type startup_hook;
+ typedef void (*shutdown_hook_type) (void);
+ extern PGDLLIMPORT shutdown_hook_type shutdown_hook;
+
/*----------
* API for handling cleanup that must occur during either ereport(ERROR)
* or ereport(FATAL) exits from a block of code. (Typical examples are
diff -cpr HEAD/src/include/utils/guc_tables.h contrib_infrastructures/src/include/utils/guc_tables.h
*** HEAD/src/include/utils/guc_tables.h Tue Sep 30 19:52:14 2008
--- contrib_infrastructures/src/include/utils/guc_tables.h Thu Nov 6 17:06:36 2008
*************** extern const char *config_enum_lookup_by
*** 242,246 ****
--- 242,247 ----
extern bool config_enum_lookup_by_name(struct config_enum *record,
const char *value, int *retval);
+ extern void DefineCustomVariable(enum config_type type, const void *variable);
#endif /* GUC_TABLES_H */
ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp> writes:
I'm submitting 2 contrib modules and there 3 patches to core for them
from me and Martin, but they confict each other and there are some hunks
and rejections already. Here is an assorted patch of them.
Can I ask you to review the patches in this form?
I've removed this item from the commitfest listing because it seems to
just confuse matters --- all the suggested patches are listed separately
under the auto_explain and pg_stat_statements entries.
regards, tom lane