summaryrefslogtreecommitdiff
path: root/src/include/commands
diff options
context:
space:
mode:
authorRobert Haas2025-03-18 12:41:12 +0000
committerRobert Haas2025-03-18 12:41:12 +0000
commitc65bc2e1d14a2d4daed7c1921ac518f2c5ac3d17 (patch)
treeffb12e651e2d3603d3f11aef0449d90bd82ac087 /src/include/commands
parent9d6db8bec19413cd0167f1e59d1af005a997bd3e (diff)
Make it possible for loadable modules to add EXPLAIN options.
Modules can use RegisterExtensionExplainOption to register new EXPLAIN options, and GetExplainExtensionId, GetExplainExtensionState, and SetExplainExtensionState to store related state inside the ExplainState object. Since this substantially increases the amount of code that needs to handle ExplainState-related tasks, move a few bits of existing code to a new file explain_state.c and add the rest of this infrastructure there. See the comments at the top of explain_state.c for further explanation of how this mechanism works. This does not yet provide a way for such such options to do anything useful. The intention is that we'll add hooks for that purpose in a separate commit. Discussion: http://postgr.es/m/CA+TgmoYSzg58hPuBmei46o8D3SKX+SZoO4K_aGQGwiRzvRApLg@mail.gmail.com Reviewed-by: Srinath Reddy <[email protected]> Reviewed-by: Andrei Lepikhov <[email protected]> Reviewed-by: Tom Lane <[email protected]> Reviewed-by: Sami Imseih <[email protected]>
Diffstat (limited to 'src/include/commands')
-rw-r--r--src/include/commands/explain.h80
-rw-r--r--src/include/commands/explain_state.h95
-rw-r--r--src/include/commands/prepare.h3
3 files changed, 110 insertions, 68 deletions
diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
index 64547bd9b9c..783f67b468a 100644
--- a/src/include/commands/explain.h
+++ b/src/include/commands/explain.h
@@ -14,70 +14,15 @@
#define EXPLAIN_H
#include "executor/executor.h"
-#include "lib/stringinfo.h"
#include "parser/parse_node.h"
-typedef enum ExplainSerializeOption
-{
- EXPLAIN_SERIALIZE_NONE,
- EXPLAIN_SERIALIZE_TEXT,
- EXPLAIN_SERIALIZE_BINARY,
-} ExplainSerializeOption;
-
-typedef enum ExplainFormat
-{
- EXPLAIN_FORMAT_TEXT,
- EXPLAIN_FORMAT_XML,
- EXPLAIN_FORMAT_JSON,
- EXPLAIN_FORMAT_YAML,
-} ExplainFormat;
-
-typedef struct ExplainWorkersState
-{
- int num_workers; /* # of worker processes the plan used */
- bool *worker_inited; /* per-worker state-initialized flags */
- StringInfoData *worker_str; /* per-worker transient output buffers */
- int *worker_state_save; /* per-worker grouping state save areas */
- StringInfo prev_str; /* saved output buffer while redirecting */
-} ExplainWorkersState;
-
-typedef struct ExplainState
-{
- StringInfo str; /* output buffer */
- /* options */
- bool verbose; /* be verbose */
- bool analyze; /* print actual times */
- bool costs; /* print estimated costs */
- bool buffers; /* print buffer usage */
- bool wal; /* print WAL usage */
- bool timing; /* print detailed node timing */
- bool summary; /* print total planning and execution timing */
- bool memory; /* print planner's memory usage information */
- bool settings; /* print modified settings */
- bool generic; /* generate a generic plan */
- ExplainSerializeOption serialize; /* serialize the query's output? */
- ExplainFormat format; /* output format */
- /* state for output formatting --- not reset for each new plan tree */
- int indent; /* current indentation level */
- List *grouping_stack; /* format-specific grouping state */
- /* state related to the current plan tree (filled by ExplainPrintPlan) */
- PlannedStmt *pstmt; /* top of plan */
- List *rtable; /* range table */
- List *rtable_names; /* alias names for RTEs */
- List *deparse_cxt; /* context list for deparsing expressions */
- Bitmapset *printed_subplans; /* ids of SubPlans we've printed */
- bool hide_workers; /* set if we find an invisible Gather */
- int rtable_size; /* length of rtable excluding the RTE_GROUP
- * entry */
- /* state related to the current plan node */
- ExplainWorkersState *workers_state; /* needed if parallel plan */
-} ExplainState;
+struct ExplainState; /* defined in explain_state.h */
/* Hook for plugins to get control in ExplainOneQuery() */
typedef void (*ExplainOneQuery_hook_type) (Query *query,
int cursorOptions,
IntoClause *into,
- ExplainState *es,
+ struct ExplainState *es,
const char *queryString,
ParamListInfo params,
QueryEnvironment *queryEnv);
@@ -91,33 +36,34 @@ extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook;
extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
ParamListInfo params, DestReceiver *dest);
extern void standard_ExplainOneQuery(Query *query, int cursorOptions,
- IntoClause *into, ExplainState *es,
+ IntoClause *into, struct ExplainState *es,
const char *queryString, ParamListInfo params,
QueryEnvironment *queryEnv);
-extern ExplainState *NewExplainState(void);
-
extern TupleDesc ExplainResultDesc(ExplainStmt *stmt);
extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into,
- ExplainState *es, ParseState *pstate,
+ struct ExplainState *es, ParseState *pstate,
ParamListInfo params);
extern void ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan,
CachedPlanSource *plansource, int plan_index,
- IntoClause *into, ExplainState *es,
+ IntoClause *into, struct ExplainState *es,
const char *queryString,
ParamListInfo params, QueryEnvironment *queryEnv,
const instr_time *planduration,
const BufferUsage *bufusage,
const MemoryContextCounters *mem_counters);
-extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc);
-extern void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainPrintPlan(struct ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainPrintTriggers(struct ExplainState *es,
+ QueryDesc *queryDesc);
-extern void ExplainPrintJITSummary(ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainPrintJITSummary(struct ExplainState *es,
+ QueryDesc *queryDesc);
-extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc);
-extern void ExplainQueryParameters(ExplainState *es, ParamListInfo params, int maxlen);
+extern void ExplainQueryText(struct ExplainState *es, QueryDesc *queryDesc);
+extern void ExplainQueryParameters(struct ExplainState *es,
+ ParamListInfo params, int maxlen);
#endif /* EXPLAIN_H */
diff --git a/src/include/commands/explain_state.h b/src/include/commands/explain_state.h
new file mode 100644
index 00000000000..925097492b9
--- /dev/null
+++ b/src/include/commands/explain_state.h
@@ -0,0 +1,95 @@
+/*-------------------------------------------------------------------------
+ *
+ * explain_state.h
+ * prototypes for explain_state.c
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994-5, Regents of the University of California
+ *
+ * src/include/commands/explain_state.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef EXPLAIN_STATE_H
+#define EXPLAIN_STATE_H
+
+#include "nodes/parsenodes.h"
+#include "nodes/plannodes.h"
+#include "parser/parse_node.h"
+
+typedef enum ExplainSerializeOption
+{
+ EXPLAIN_SERIALIZE_NONE,
+ EXPLAIN_SERIALIZE_TEXT,
+ EXPLAIN_SERIALIZE_BINARY,
+} ExplainSerializeOption;
+
+typedef enum ExplainFormat
+{
+ EXPLAIN_FORMAT_TEXT,
+ EXPLAIN_FORMAT_XML,
+ EXPLAIN_FORMAT_JSON,
+ EXPLAIN_FORMAT_YAML,
+} ExplainFormat;
+
+typedef struct ExplainWorkersState
+{
+ int num_workers; /* # of worker processes the plan used */
+ bool *worker_inited; /* per-worker state-initialized flags */
+ StringInfoData *worker_str; /* per-worker transient output buffers */
+ int *worker_state_save; /* per-worker grouping state save areas */
+ StringInfo prev_str; /* saved output buffer while redirecting */
+} ExplainWorkersState;
+
+typedef struct ExplainState
+{
+ StringInfo str; /* output buffer */
+ /* options */
+ bool verbose; /* be verbose */
+ bool analyze; /* print actual times */
+ bool costs; /* print estimated costs */
+ bool buffers; /* print buffer usage */
+ bool wal; /* print WAL usage */
+ bool timing; /* print detailed node timing */
+ bool summary; /* print total planning and execution timing */
+ bool memory; /* print planner's memory usage information */
+ bool settings; /* print modified settings */
+ bool generic; /* generate a generic plan */
+ ExplainSerializeOption serialize; /* serialize the query's output? */
+ ExplainFormat format; /* output format */
+ /* state for output formatting --- not reset for each new plan tree */
+ int indent; /* current indentation level */
+ List *grouping_stack; /* format-specific grouping state */
+ /* state related to the current plan tree (filled by ExplainPrintPlan) */
+ PlannedStmt *pstmt; /* top of plan */
+ List *rtable; /* range table */
+ List *rtable_names; /* alias names for RTEs */
+ List *deparse_cxt; /* context list for deparsing expressions */
+ Bitmapset *printed_subplans; /* ids of SubPlans we've printed */
+ bool hide_workers; /* set if we find an invisible Gather */
+ int rtable_size; /* length of rtable excluding the RTE_GROUP
+ * entry */
+ /* state related to the current plan node */
+ ExplainWorkersState *workers_state; /* needed if parallel plan */
+ /* extensions */
+ void **extension_state;
+ int extension_state_allocated;
+} ExplainState;
+
+typedef void (*ExplainOptionHandler) (ExplainState *, DefElem *, ParseState *);
+
+extern ExplainState *NewExplainState(void);
+extern void ParseExplainOptionList(ExplainState *es, List *options,
+ ParseState *pstate);
+
+extern int GetExplainExtensionId(const char *extension_name);
+extern void *GetExplainExtensionState(ExplainState *es, int extension_id);
+extern void SetExplainExtensionState(ExplainState *es, int extension_id,
+ void *opaque);
+
+extern void RegisterExtensionExplainOption(const char *option_name,
+ ExplainOptionHandler handler);
+extern bool ApplyExtensionExplainOption(ExplainState *es, DefElem *opt,
+ ParseState *pstate);
+
+#endif /* EXPLAIN_STATE_H */
diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h
index b9533f1af84..08daac8c926 100644
--- a/src/include/commands/prepare.h
+++ b/src/include/commands/prepare.h
@@ -13,8 +13,9 @@
#ifndef PREPARE_H
#define PREPARE_H
-#include "commands/explain.h"
+#include "commands/explain_state.h"
#include "datatype/timestamp.h"
+#include "tcop/dest.h"
#include "utils/plancache.h"
/*