diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 8e48b94d4a..2a289b8b94 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -599,8 +599,12 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, ExplainCloseGroup("Query", NULL, true, es); } +/* + * ExplainPrintSettings - + * Print summary of modified settings affecting query planning. + */ static void -ExplainShowSettings(ExplainState *es) +ExplainPrintSettings(ExplainState *es) { int num; struct config_generic **gucs; @@ -700,10 +704,10 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc) ExplainNode(ps, NIL, NULL, NULL, es); /* - * If requested, include information about GUC parameters that don't - * match the built-in defaults. + * If requested, include information about GUC parameters with values + * that don't match the built-in defaults. */ - ExplainShowSettings(es); + ExplainPrintSettings(es); } /* diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 7306d7c232..39f844ebc5 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4532,6 +4532,7 @@ static struct config_generic **guc_variables; /* Current number of variables contained in the vector */ static int num_guc_variables; +static int num_guc_explain_variables; /* Vector capacity */ static int size_guc_variables; @@ -4796,6 +4797,7 @@ build_guc_variables(void) { int size_vars; int num_vars = 0; + int num_explain_vars = 0; struct config_generic **guc_vars; int i; @@ -4806,6 +4808,9 @@ build_guc_variables(void) /* Rather than requiring vartype to be filled in by hand, do this: */ conf->gen.vartype = PGC_BOOL; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesInt[i].gen.name; i++) @@ -4814,6 +4819,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_INT; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesReal[i].gen.name; i++) @@ -4822,6 +4830,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_REAL; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesString[i].gen.name; i++) @@ -4830,6 +4841,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_STRING; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesEnum[i].gen.name; i++) @@ -4838,6 +4852,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_ENUM; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } /* @@ -4869,6 +4886,7 @@ build_guc_variables(void) free(guc_variables); guc_variables = guc_vars; num_guc_variables = num_vars; + num_guc_explain_variables = num_explain_vars; size_guc_variables = size_vars; qsort((void *) guc_variables, num_guc_variables, sizeof(struct config_generic *), guc_var_compare); @@ -8819,6 +8837,11 @@ ShowAllGUCConfig(DestReceiver *dest) end_tup_output(tstate); } +/* + * Returns an array of modified GUC options to show in EXPLAIN. Only options + * related to query planning (marked with GUC_EXPLAIN), with values different + * from built-in defaults. + */ struct config_generic ** get_explain_guc_options(int *num) { @@ -8826,7 +8849,13 @@ get_explain_guc_options(int *num) struct config_generic **result; *num = 0; - result = palloc(sizeof(struct config_generic *) * num_guc_variables); + + /* + * Allocate enough space to fit all GUC_EXPLAIN options. We may not + * need all the space, but there are fairly few such options so we + * don't waste a lot of memory. + */ + result = palloc(sizeof(struct config_generic *) * num_guc_explain_variables); for (i = 0; i < num_guc_variables; i++) { @@ -8894,6 +8923,8 @@ get_explain_guc_options(int *num) /* assign to the values array */ result[*num] = conf; *num = *num + 1; + + Assert(*num <= num_guc_explain_variables); } return result;