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 */
