Skip to content

Commit 5e1f3b9

Browse files
committed
Make Bitmapsets be valid Nodes.
Add a NodeTag field to struct Bitmapset. This is free because of alignment considerations on 64-bit hardware. While it adds some space on 32-bit machines, we aren't optimizing for that case anymore. The advantage is that data structures such as Lists of Bitmapsets are now first-class objects to the Node infrastructure, and don't require special-case code to handle. This patch includes removal of one such special case, in indxpath.c: bms_equal_any() can now be replaced by list_member(). There may be more existing code that could be simplified, but I didn't look very hard. We also get to drop the read_write_ignore annotations on a couple of RelOptInfo fields. The outfuncs/readfuncs support is arranged so that nothing changes in the string representation of a Bitmapset field; therefore, this doesn't need a catversion bump. Amit Langote and Tom Lane Discussion: https://postgr.es/m/109089.1668197158@sss.pgh.pa.us
1 parent 9c7eb9d commit 5e1f3b9

File tree

12 files changed

+68
-30
lines changed

12 files changed

+68
-30
lines changed

src/backend/nodes/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ node_headers = \
5252
commands/trigger.h \
5353
executor/tuptable.h \
5454
foreign/fdwapi.h \
55+
nodes/bitmapset.h \
5556
nodes/extensible.h \
5657
nodes/lockoptions.h \
5758
nodes/replnodes.h \

src/backend/nodes/bitmapset.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ bms_make_singleton(int x)
194194
wordnum = WORDNUM(x);
195195
bitnum = BITNUM(x);
196196
result = (Bitmapset *) palloc0(BITMAPSET_SIZE(wordnum + 1));
197+
result->type = T_Bitmapset;
197198
result->nwords = wordnum + 1;
198199
result->words[wordnum] = ((bitmapword) 1 << bitnum);
199200
return result;
@@ -852,6 +853,7 @@ bms_add_range(Bitmapset *a, int lower, int upper)
852853
if (a == NULL)
853854
{
854855
a = (Bitmapset *) palloc0(BITMAPSET_SIZE(uwordnum + 1));
856+
a->type = T_Bitmapset;
855857
a->nwords = uwordnum + 1;
856858
}
857859
else if (uwordnum >= a->nwords)

src/backend/nodes/copyfuncs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ _copyExtensibleNode(const ExtensibleNode *from)
160160
return newnode;
161161
}
162162

163+
static Bitmapset *
164+
_copyBitmapset(const Bitmapset *from)
165+
{
166+
return bms_copy(from);
167+
}
168+
163169

164170
/*
165171
* copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h

src/backend/nodes/equalfuncs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ _equalA_Const(const A_Const *a, const A_Const *b)
145145
return true;
146146
}
147147

148+
static bool
149+
_equalBitmapset(const Bitmapset *a, const Bitmapset *b)
150+
{
151+
return bms_equal(a, b);
152+
}
153+
148154
/*
149155
* Lists are handled specially
150156
*/

src/backend/nodes/gen_node_support.pl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ sub elem
6565
commands/trigger.h
6666
executor/tuptable.h
6767
foreign/fdwapi.h
68+
nodes/bitmapset.h
6869
nodes/extensible.h
6970
nodes/lockoptions.h
7071
nodes/replnodes.h

src/backend/nodes/outfuncs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,9 @@ _outList(StringInfo str, const List *node)
314314
* converts a bitmap set of integers
315315
*
316316
* Note: the output format is "(b int int ...)", similar to an integer List.
317+
*
318+
* We export this function for use by extensions that define extensible nodes.
319+
* That's somewhat historical, though, because calling outNode() will work.
317320
*/
318321
void
319322
outBitmapset(StringInfo str, const Bitmapset *bms)
@@ -844,6 +847,8 @@ outNode(StringInfo str, const void *obj)
844847
_outString(str, (String *) obj);
845848
else if (IsA(obj, BitString))
846849
_outBitString(str, (BitString *) obj);
850+
else if (IsA(obj, Bitmapset))
851+
outBitmapset(str, (Bitmapset *) obj);
847852
else
848853
{
849854
appendStringInfoChar(str, '{');

src/backend/nodes/read.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <ctype.h>
2323

2424
#include "common/string.h"
25+
#include "nodes/bitmapset.h"
2526
#include "nodes/pg_list.h"
2627
#include "nodes/readfuncs.h"
2728
#include "nodes/value.h"
@@ -347,6 +348,7 @@ nodeRead(const char *token, int tok_len)
347348
* Could be an integer list: (i int int ...)
348349
* or an OID list: (o int int ...)
349350
* or an XID list: (x int int ...)
351+
* or a bitmapset: (b int int ...)
350352
* or a list of nodes/values: (node node ...)
351353
*----------
352354
*/
@@ -372,6 +374,7 @@ nodeRead(const char *token, int tok_len)
372374
tok_len, token);
373375
l = lappend_int(l, val);
374376
}
377+
result = (Node *) l;
375378
}
376379
else if (tok_len == 1 && token[0] == 'o')
377380
{
@@ -392,6 +395,7 @@ nodeRead(const char *token, int tok_len)
392395
tok_len, token);
393396
l = lappend_oid(l, val);
394397
}
398+
result = (Node *) l;
395399
}
396400
else if (tok_len == 1 && token[0] == 'x')
397401
{
@@ -412,6 +416,30 @@ nodeRead(const char *token, int tok_len)
412416
tok_len, token);
413417
l = lappend_xid(l, val);
414418
}
419+
result = (Node *) l;
420+
}
421+
else if (tok_len == 1 && token[0] == 'b')
422+
{
423+
/* Bitmapset -- see also _readBitmapset() */
424+
Bitmapset *bms = NULL;
425+
426+
for (;;)
427+
{
428+
int val;
429+
char *endptr;
430+
431+
token = pg_strtok(&tok_len);
432+
if (token == NULL)
433+
elog(ERROR, "unterminated Bitmapset structure");
434+
if (tok_len == 1 && token[0] == ')')
435+
break;
436+
val = (int) strtol(token, &endptr, 10);
437+
if (endptr != token + tok_len)
438+
elog(ERROR, "unrecognized integer: \"%.*s\"",
439+
tok_len, token);
440+
bms = bms_add_member(bms, val);
441+
}
442+
result = (Node *) bms;
415443
}
416444
else
417445
{
@@ -426,8 +454,8 @@ nodeRead(const char *token, int tok_len)
426454
if (token == NULL)
427455
elog(ERROR, "unterminated List structure");
428456
}
457+
result = (Node *) l;
429458
}
430-
result = (Node *) l;
431459
break;
432460
}
433461
case RIGHT_PAREN:

src/backend/nodes/readfuncs.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ nullable_string(const char *token, int length)
194194

195195
/*
196196
* _readBitmapset
197+
*
198+
* Note: this code is used in contexts where we know that a Bitmapset
199+
* is expected. There is equivalent code in nodeRead() that can read a
200+
* Bitmapset when we come across one in other contexts.
197201
*/
198202
static Bitmapset *
199203
_readBitmapset(void)
@@ -234,7 +238,8 @@ _readBitmapset(void)
234238
}
235239

236240
/*
237-
* for use by extensions which define extensible nodes
241+
* We export this function for use by extensions that define extensible nodes.
242+
* That's somewhat historical, though, because calling nodeRead() will work.
238243
*/
239244
Bitmapset *
240245
readBitmapset(void)

src/backend/optimizer/path/indxpath.c

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ static void get_join_index_paths(PlannerInfo *root, RelOptInfo *rel,
9999
List **considered_relids);
100100
static bool eclass_already_used(EquivalenceClass *parent_ec, Relids oldrelids,
101101
List *indexjoinclauses);
102-
static bool bms_equal_any(Relids relids, List *relids_list);
103102
static void get_index_paths(PlannerInfo *root, RelOptInfo *rel,
104103
IndexOptInfo *index, IndexClauseSet *clauses,
105104
List **bitindexpaths);
@@ -370,8 +369,8 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
370369
Path *path = (Path *) lfirst(lc);
371370
Relids required_outer = PATH_REQ_OUTER(path);
372371

373-
if (!bms_equal_any(required_outer, all_path_outers))
374-
all_path_outers = lappend(all_path_outers, required_outer);
372+
all_path_outers = list_append_unique(all_path_outers,
373+
required_outer);
375374
}
376375

377376
/* Now, for each distinct parameterization set ... */
@@ -517,7 +516,7 @@ consider_index_join_outer_rels(PlannerInfo *root, RelOptInfo *rel,
517516
int num_considered_relids;
518517

519518
/* If we already tried its relids set, no need to do so again */
520-
if (bms_equal_any(clause_relids, *considered_relids))
519+
if (list_member(*considered_relids, clause_relids))
521520
continue;
522521

523522
/*
@@ -612,7 +611,7 @@ get_join_index_paths(PlannerInfo *root, RelOptInfo *rel,
612611
int indexcol;
613612

614613
/* If we already considered this relids set, don't repeat the work */
615-
if (bms_equal_any(relids, *considered_relids))
614+
if (list_member(*considered_relids, relids))
616615
return;
617616

618617
/* Identify indexclauses usable with this relids set */
@@ -694,25 +693,6 @@ eclass_already_used(EquivalenceClass *parent_ec, Relids oldrelids,
694693
return false;
695694
}
696695

697-
/*
698-
* bms_equal_any
699-
* True if relids is bms_equal to any member of relids_list
700-
*
701-
* Perhaps this should be in bitmapset.c someday.
702-
*/
703-
static bool
704-
bms_equal_any(Relids relids, List *relids_list)
705-
{
706-
ListCell *lc;
707-
708-
foreach(lc, relids_list)
709-
{
710-
if (bms_equal(relids, (Relids) lfirst(lc)))
711-
return true;
712-
}
713-
return false;
714-
}
715-
716696

717697
/*
718698
* get_index_paths

src/include/nodes/bitmapset.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#ifndef BITMAPSET_H
2121
#define BITMAPSET_H
2222

23+
#include "nodes/nodes.h"
24+
2325
/*
2426
* Forward decl to save including pg_list.h
2527
*/
@@ -48,6 +50,9 @@ typedef int32 signedbitmapword; /* must be the matching signed type */
4850

4951
typedef struct Bitmapset
5052
{
53+
pg_node_attr(custom_copy_equal, special_read_write)
54+
55+
NodeTag type;
5156
int nwords; /* number of words in array */
5257
bitmapword words[FLEXIBLE_ARRAY_MEMBER]; /* really [nwords] */
5358
} Bitmapset;

src/include/nodes/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ node_support_input_i = [
1313
'commands/trigger.h',
1414
'executor/tuptable.h',
1515
'foreign/fdwapi.h',
16+
'nodes/bitmapset.h',
1617
'nodes/extensible.h',
1718
'nodes/lockoptions.h',
1819
'nodes/replnodes.h',

src/include/nodes/pathnodes.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -911,13 +911,11 @@ typedef struct RelOptInfo
911911

912912
/*
913913
* cache space for remembering if we have proven this relation unique
914-
*
915-
* can't print unique_for_rels/non_unique_for_rels; BMSes aren't Nodes
916914
*/
917915
/* known unique for these other relid set(s) */
918-
List *unique_for_rels pg_node_attr(read_write_ignore);
916+
List *unique_for_rels;
919917
/* known not unique for these set(s) */
920-
List *non_unique_for_rels pg_node_attr(read_write_ignore);
918+
List *non_unique_for_rels;
921919

922920
/*
923921
* used by various scans and joins:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy