Bitmapsets as Nodes
Hi,
For a couple of patches that I am working on ([1]https://commitfest.postgresql.org/40/3478/, [2]https://commitfest.postgresql.org/40/3224/), I have needed
to put Bitmapsets into a List that is in turn part of a Plan tree or a
Node tree that may be written (using outNode) and read (using
nodeRead). Bitmapsets not being a Node themselves causes the
write/read of such Plan/Node trees (containing Bitmapsets in a List)
to not work properly.
So, I included a patch in both of those threads to add minimal support
for Bitmapsets to be added into a Plan/Node tree without facing the
aforementioned problem, though Peter E suggested [3]/messages/by-id/94353655-c177-1f55-7afb-b2090de33341@enterprisedb.com that it would be
a good idea to discuss it more generally in a separate thread, so this
email. Attached a patch to make the infrastructure changes necessary
to allow adding Bitmapsets as Nodes, though I have not changed any of
the existing Bitmapset that are added either to Query or to
PlannedStmt to use that infrastructure. That is, by setting their
NodeTag and changing gen_node_support.pl to emit
WRITE/READ_NODE_FIELD() instead of WRITE/READ_BITMAPSET_FIELD() for
any Bitmapsets encountered in a Node tree. One thing I am not quite
sure about is who would be setting the NodeTag, the existing routines
in bitmapset.c, or if we should add wrappers that do.
Actually, Tom had posted about exactly the same thing last year [4]/messages/by-id/2847014.1611971629@sss.pgh.pa.us,
though trying to make Bitmapset Nodes became unnecessary after he
resolved the problem that required making Bitmapsets Nodes by other
means -- by getting rid of the field that was a List of Bitmapset
altogether. Maybe I should try to do the same in the case of both [1]https://commitfest.postgresql.org/40/3478/
and [2]https://commitfest.postgresql.org/40/3224/? In fact, I have tried getting rid of the need for List of
Bitmapset for [1]https://commitfest.postgresql.org/40/3478/, and I like the alternative better in that case, but
for [2]https://commitfest.postgresql.org/40/3224/, it still seems that a List of Bitmapset may be better than
List of some-new-Node-containing-the-Bitmapset.
--
Thanks, Amit Langote
EDB: http://www.enterprisedb.com
[1]: https://commitfest.postgresql.org/40/3478/
[2]: https://commitfest.postgresql.org/40/3224/
[3]: /messages/by-id/94353655-c177-1f55-7afb-b2090de33341@enterprisedb.com
[4]: /messages/by-id/2847014.1611971629@sss.pgh.pa.us
Attachments:
v1-0001-Allow-adding-Bitmapsets-as-Nodes-into-plan-trees.patchapplication/octet-stream; name=v1-0001-Allow-adding-Bitmapsets-as-Nodes-into-plan-trees.patchDownload
From 61bd436b8312115cd6b6c56d8801cb15c1c341c2 Mon Sep 17 00:00:00 2001
From: amitlan <amitlangote09@gmail.com>
Date: Thu, 6 Oct 2022 17:31:37 +0900
Subject: [PATCH v1] Allow adding Bitmapsets as Nodes into plan trees
Note that this only adds some infrastructure bits and none of the
existing bitmapsets that are added to plan trees have been changed
to instead add the Node version. So, the plan trees, or really the
bitmapsets contained in them, look the same as before as far as
Node write/read functionality is concerned.
This is needed, because it is not currently possible to write and
then read back Bitmapsets that are not direct members of write/read
capable Nodes; for example, if one needs to add a List of Bitmapsets
to a plan tree. The most straightforward way to do that is to make
Bitmapsets be written with outNode() and read with nodeRead().
---
src/backend/nodes/Makefile | 3 ++-
src/backend/nodes/copyfuncs.c | 11 +++++++++++
src/backend/nodes/equalfuncs.c | 6 ++++++
src/backend/nodes/gen_node_support.pl | 1 +
src/backend/nodes/outfuncs.c | 11 +++++++++++
src/backend/nodes/readfuncs.c | 4 ++++
src/include/nodes/bitmapset.h | 5 +++++
src/include/nodes/meson.build | 1 +
8 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/src/backend/nodes/Makefile b/src/backend/nodes/Makefile
index 7450e191ee..da5307771b 100644
--- a/src/backend/nodes/Makefile
+++ b/src/backend/nodes/Makefile
@@ -57,7 +57,8 @@ node_headers = \
nodes/replnodes.h \
nodes/supportnodes.h \
nodes/value.h \
- utils/rel.h
+ utils/rel.h \
+ nodes/bitmapset.h
# see also catalog/Makefile for an explanation of these make rules
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index e76fda8eba..1482019327 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -160,6 +160,17 @@ _copyExtensibleNode(const ExtensibleNode *from)
return newnode;
}
+/* Custom copy routine for Node bitmapsets */
+static Bitmapset *
+_copyBitmapset(const Bitmapset *from)
+{
+ Bitmapset *newnode = bms_copy(from);
+
+ newnode->type = T_Bitmapset;
+
+ return newnode;
+}
+
/*
* copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 0373aa30fe..e8706c461a 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -210,6 +210,12 @@ _equalList(const List *a, const List *b)
return true;
}
+/* Custom equal routine for Node bitmapsets */
+static bool
+_equalBitmapset(const Bitmapset *a, const Bitmapset *b)
+{
+ return bms_equal(a, b);
+}
/*
* equal
diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index 81b8c184a9..ccb5aff874 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -71,6 +71,7 @@ my @all_input_files = qw(
nodes/supportnodes.h
nodes/value.h
utils/rel.h
+ nodes/bitmapset.h
);
# Nodes from these input files are automatically treated as nodetag_only.
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 64c65f060b..b3ffd8cec2 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -328,6 +328,17 @@ outBitmapset(StringInfo str, const Bitmapset *bms)
appendStringInfoChar(str, ')');
}
+/* Custom write routine for Node bitmapsets */
+static void
+_outBitmapset(StringInfo str, const Bitmapset *bms)
+{
+ Assert(IsA(bms, Bitmapset));
+ WRITE_NODE_TYPE("BITMAPSET");
+
+ outBitmapset(str, bms);
+}
+
+
/*
* Print the value of a Datum given its type.
*/
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index b4ff855f7c..a5372a6a60 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -230,6 +230,10 @@ _readBitmapset(void)
result = bms_add_member(result, val);
}
+ /* Matches what _copyBitmapset() does. */
+ if (result)
+ result->type = T_Bitmapset;
+
return result;
}
diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h
index 75b5ce1a8e..9046ca177f 100644
--- a/src/include/nodes/bitmapset.h
+++ b/src/include/nodes/bitmapset.h
@@ -20,6 +20,8 @@
#ifndef BITMAPSET_H
#define BITMAPSET_H
+#include "nodes/nodes.h"
+
/*
* Forward decl to save including pg_list.h
*/
@@ -48,6 +50,9 @@ typedef int32 signedbitmapword; /* must be the matching signed type */
typedef struct Bitmapset
{
+ pg_node_attr(custom_copy_equal, custom_read_write)
+
+ NodeTag type;
int nwords; /* number of words in array */
bitmapword words[FLEXIBLE_ARRAY_MEMBER]; /* really [nwords] */
} Bitmapset;
diff --git a/src/include/nodes/meson.build b/src/include/nodes/meson.build
index b7df232081..94701af8e1 100644
--- a/src/include/nodes/meson.build
+++ b/src/include/nodes/meson.build
@@ -19,6 +19,7 @@ node_support_input_i = [
'nodes/supportnodes.h',
'nodes/value.h',
'utils/rel.h',
+ 'nodes/bitmapset.h',
]
node_support_input = []
--
2.35.3
On Mon, Oct 17, 2022 at 6:30 PM Amit Langote <amitlangote09@gmail.com> wrote:
For a couple of patches that I am working on ([1], [2]), I have needed
to put Bitmapsets into a List that is in turn part of a Plan tree or a
Node tree that may be written (using outNode) and read (using
nodeRead). Bitmapsets not being a Node themselves causes the
write/read of such Plan/Node trees (containing Bitmapsets in a List)
to not work properly.So, I included a patch in both of those threads to add minimal support
for Bitmapsets to be added into a Plan/Node tree without facing the
aforementioned problem, though Peter E suggested [3] that it would be
a good idea to discuss it more generally in a separate thread, so this
email. Attached a patch to make the infrastructure changes necessary
to allow adding Bitmapsets as Nodes, though I have not changed any of
the existing Bitmapset that are added either to Query or to
PlannedStmt to use that infrastructure. That is, by setting their
NodeTag and changing gen_node_support.pl to emit
WRITE/READ_NODE_FIELD() instead of WRITE/READ_BITMAPSET_FIELD() for
any Bitmapsets encountered in a Node tree. One thing I am not quite
sure about is who would be setting the NodeTag, the existing routines
in bitmapset.c, or if we should add wrappers that do.Actually, Tom had posted about exactly the same thing last year [4],
though trying to make Bitmapset Nodes became unnecessary after he
resolved the problem that required making Bitmapsets Nodes by other
means -- by getting rid of the field that was a List of Bitmapset
altogether. Maybe I should try to do the same in the case of both [1]
and [2]? In fact, I have tried getting rid of the need for List of
Bitmapset for [1], and I like the alternative better in that case, but
for [2], it still seems that a List of Bitmapset may be better than
List of some-new-Node-containing-the-Bitmapset.
FTR, this has been taken care of in 5e1f3b9ebf6e5.
--
Thanks, Amit Langote
EDB: http://www.enterprisedb.com