summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2025-10-07 12:09:30 -0400
committerRobert Haas <rhaas@postgresql.org>2025-10-07 12:09:30 -0400
commit0132dddab33a6eae2d3d63eda9f053e745fedb06 (patch)
tree0b3da24f8444dace5c01534186107c4cdd939c12 /src/include
parentafd532c3a80c12a9c0f836c5e4fc3cfe6503b91f (diff)
Allow private state in certain planner data structures.
Extension that make extensive use of planner hooks may want to coordinate their efforts, for example to avoid duplicate computation, but that's currently difficult because there's no really good way to pass data between different hooks. To make that easier, allow for storage of extension-managed private state in PlannerGlobal, PlannerInfo, and RelOptInfo, along very similar lines to what we have permitted for ExplainState since commit c65bc2e1d14a2d4daed7c1921ac518f2c5ac3d17. Reviewed-by: Andrei Lepikhov <lepihov@gmail.com> Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: http://postgr.es/m/CA+TgmoYWKHU2hKr62Toyzh-kTDEnMDeLw7gkOOnjL-TnOUq0kQ@mail.gmail.com
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/pathnodes.h12
-rw-r--r--src/include/optimizer/extendplan.h72
2 files changed, 84 insertions, 0 deletions
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 7ee9a7a68d8..554d7c3ef67 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -185,6 +185,10 @@ typedef struct PlannerGlobal
/* hash table for NOT NULL attnums of relations */
struct HTAB *rel_notnullatts_hash pg_node_attr(read_write_ignore);
+
+ /* extension state */
+ void **extension_state pg_node_attr(read_write_ignore);
+ int extension_state_allocated;
} PlannerGlobal;
/* macro for fetching the Plan associated with a SubPlan node */
@@ -586,6 +590,10 @@ struct PlannerInfo
/* PartitionPruneInfos added in this query's plan. */
List *partPruneInfos;
+
+ /* extension state */
+ void **extension_state pg_node_attr(read_write_ignore);
+ int extension_state_allocated;
};
@@ -1097,6 +1105,10 @@ typedef struct RelOptInfo
List **partexprs pg_node_attr(read_write_ignore);
/* Nullable partition key expressions */
List **nullable_partexprs pg_node_attr(read_write_ignore);
+
+ /* extension state */
+ void **extension_state pg_node_attr(read_write_ignore);
+ int extension_state_allocated;
} RelOptInfo;
/*
diff --git a/src/include/optimizer/extendplan.h b/src/include/optimizer/extendplan.h
new file mode 100644
index 00000000000..de9618761dd
--- /dev/null
+++ b/src/include/optimizer/extendplan.h
@@ -0,0 +1,72 @@
+/*-------------------------------------------------------------------------
+ *
+ * extendplan.h
+ * Extend core planner objects with additional private state
+ *
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/optimizer/extendplan.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef EXTENDPLAN_H
+#define EXTENDPLAN_H
+
+#include "nodes/pathnodes.h"
+
+extern int GetPlannerExtensionId(const char *extension_name);
+
+/*
+ * Get extension-specific state from a PlannerGlobal.
+ */
+static inline void *
+GetPlannerGlobalExtensionState(PlannerGlobal *glob, int extension_id)
+{
+ Assert(extension_id >= 0);
+
+ if (extension_id >= glob->extension_state_allocated)
+ return NULL;
+
+ return glob->extension_state[extension_id];
+}
+
+/*
+ * Get extension-specific state from a PlannerInfo.
+ */
+static inline void *
+GetPlannerInfoExtensionState(PlannerInfo *root, int extension_id)
+{
+ Assert(extension_id >= 0);
+
+ if (extension_id >= root->extension_state_allocated)
+ return NULL;
+
+ return root->extension_state[extension_id];
+}
+
+/*
+ * Get extension-specific state from a PlannerInfo.
+ */
+static inline void *
+GetRelOptInfoExtensionState(RelOptInfo *rel, int extension_id)
+{
+ Assert(extension_id >= 0);
+
+ if (extension_id >= rel->extension_state_allocated)
+ return NULL;
+
+ return rel->extension_state[extension_id];
+}
+
+/* Functions to store private state into various planner objects */
+extern void SetPlannerGlobalExtensionState(PlannerGlobal *glob,
+ int extension_id,
+ void *opaque);
+extern void SetPlannerInfoExtensionState(PlannerInfo *root, int extension_id,
+ void *opaque);
+extern void SetRelOptInfoExtensionState(RelOptInfo *rel, int extension_id,
+ void *opaque);
+
+#endif