Thread
Commits
-
Verify range bounds to bms_add_range when necessary
- d25d45e4d922 12.0 landed
- a0655ba68fb5 11.0 landed
-
Change bms_add_range to be a no-op for empty ranges
- 1b68010518c9 12.0 landed
- 192d1bbf9969 11.0 landed
-
negative bitmapset member not allowed Error with partition pruning
Rajkumar Raghuwanshi <rajkumar.raghuwanshi@enterprisedb.com> — 2018-07-26T10:10:01Z
Hi, I am getting "ERROR: negative bitmapset member not allowed" when enable_partition_pruning set to true with below test case. [edb@localhost bin]$ ./psql postgres psql (12devel) Type "help" for help. postgres=# SET enable_partition_pruning TO on; SET postgres=# CREATE TABLE part (a INT, b INT) PARTITION BY LIST(a); CREATE TABLE postgres=# CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2); CREATE TABLE postgres=# CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE(a); CREATE TABLE postgres=# CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT; CREATE TABLE postgres=# INSERT INTO part VALUES (-1,-1),(1,1),(2,NULL),(NULL,-2),(NULL,NULL); INSERT 0 5 postgres=# EXPLAIN (COSTS OFF) *postgres-# SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3;ERROR: negative bitmapset member not allowed* postgres=# SET enable_partition_pruning TO off; SET postgres=# EXPLAIN (COSTS OFF) SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3; QUERY PLAN ------------------------------------------------------------------------ Sort Sort Key: ((part_p1.tableoid)::regclass), part_p1.a, part_p1.b -> Append -> Seq Scan on part_p1 Filter: (a IS NULL) -> Seq Scan on part_p2_p1 Filter: (a IS NULL) (7 rows) postgres=# Thanks & Regards, Rajkumar Raghuwanshi QMG, EnterpriseDB Corporation -
Re: negative bitmapset member not allowed Error with partition pruning
Tom Lane <tgl@sss.pgh.pa.us> — 2018-07-26T16:28:23Z
Rajkumar Raghuwanshi <rajkumar.raghuwanshi@enterprisedb.com> writes: > I am getting "ERROR: negative bitmapset member not allowed" when > enable_partition_pruning set to true with below test case. Confirmed here. It's failing in perform_pruning_combine_step, which reaches this: result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); with boundinfo->ndatums == 0. It's not clear to me whether that situation should be impossible or not. If it is valid, perhaps all we need is something like if (boundinfo->ndatums > 0) result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); else result->bound_offsets = NULL; although that then opens the question of whether downstream code is OK with bound_offsets being empty. (BTW, I'm not sure that it was wise to design bms_add_range to fail for empty ranges. Maybe it'd be better to redefine it as a no-op for upper < lower?) regards, tom lane -
Re: negative bitmapset member not allowed Error with partition pruning
Amit Langote <langote_amit_f8@lab.ntt.co.jp> — 2018-07-27T01:35:34Z
On 2018/07/27 1:28, Tom Lane wrote: > Rajkumar Raghuwanshi <rajkumar.raghuwanshi@enterprisedb.com> writes: >> I am getting "ERROR: negative bitmapset member not allowed" when >> enable_partition_pruning set to true with below test case. Thanks Rajkumar. > Confirmed here. It's failing in perform_pruning_combine_step, > which reaches this: > > result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); > > with boundinfo->ndatums == 0. It's not clear to me whether that situation > should be impossible or not. If it is valid, perhaps all we need is > something like > > if (boundinfo->ndatums > 0) > result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); > else > result->bound_offsets = NULL; > > although that then opens the question of whether downstream code is > OK with bound_offsets being empty. Yeah, this seems to be the only possible fix and I checked that downstream code is fine with bound_offsets being NULL/empty. Actually, the code that's concerned with bound offsets is limited to partprune.c, because we don't propagate bound offsets themselves outside this file. I found one more place in get_matching_hash_bounds where I thought maybe it'd be a good idea to add this check (if ndatums > 0), but then realized that that would become dead code as the upstream code takes care of the 0 hash partitions case. So, maybe an Assert (ndatums > 0) would be better. Attached find a patch that does both. > (BTW, I'm not sure that it was wise to design bms_add_range to fail for > empty ranges. Maybe it'd be better to redefine it as a no-op for > upper < lower?) FWIW, I was thankful that David those left those checks there, because it helped expose quite a few bugs when writing this code or perhaps that was his intention to begin with, but maybe he thinks differently now (?). Thanks, Amit
-
Re: negative bitmapset member not allowed Error with partition pruning
David Rowley <david.rowley@2ndquadrant.com> — 2018-07-27T02:42:45Z
On 27 July 2018 at 13:35, Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> wrote: > On 2018/07/27 1:28, Tom Lane wrote: >> (BTW, I'm not sure that it was wise to design bms_add_range to fail for >> empty ranges. Maybe it'd be better to redefine it as a no-op for >> upper < lower?) > > FWIW, I was thankful that David those left those checks there, because it > helped expose quite a few bugs when writing this code or perhaps that was > his intention to begin with, but maybe he thinks differently now (?). I think it's more useful to keep as a bug catcher, although I do understand the thinking behind just having it be a no-op. Partition pruning is complex code so I think additional caution is warranted. People are more likely to notice the error and complain. It's likely especially useful with tools like sqlsmith, as I imagine it does not validate the actual results of queries (does it?). but I'm pretty sure that the ERROR would get flagged up. -- David Rowley http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: negative bitmapset member not allowed Error with partition pruning
Tom Lane <tgl@sss.pgh.pa.us> — 2018-07-27T03:14:45Z
David Rowley <david.rowley@2ndquadrant.com> writes: > On 27 July 2018 at 13:35, Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> wrote: >> On 2018/07/27 1:28, Tom Lane wrote: >>> (BTW, I'm not sure that it was wise to design bms_add_range to fail for >>> empty ranges. Maybe it'd be better to redefine it as a no-op for >>> upper < lower?) >> FWIW, I was thankful that David those left those checks there, because it >> helped expose quite a few bugs when writing this code or perhaps that was >> his intention to begin with, but maybe he thinks differently now (?). > I think it's more useful to keep as a bug catcher, although I do > understand the thinking behind just having it be a no-op. Well, my thinking is that it helps nobody if call sites have to have explicit workarounds for a totally-arbitrary refusal to handle edge cases in the primitive functions. I do not think that is good software design. If you want to have assertions that particular call sites are specifying nonempty ranges, put those in the call sites where it's important. But as-is, this seems like, say, defining foreach() to blow up on an empty list. regards, tom lane
-
Re: negative bitmapset member not allowed Error with partition pruning
Amit Langote <langote_amit_f8@lab.ntt.co.jp> — 2018-07-27T04:23:11Z
On 2018/07/27 12:14, Tom Lane wrote: > David Rowley <david.rowley@2ndquadrant.com> writes: >> On 27 July 2018 at 13:35, Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> wrote: >>> On 2018/07/27 1:28, Tom Lane wrote: >>>> (BTW, I'm not sure that it was wise to design bms_add_range to fail for >>>> empty ranges. Maybe it'd be better to redefine it as a no-op for >>>> upper < lower?) > >>> FWIW, I was thankful that David those left those checks there, because it >>> helped expose quite a few bugs when writing this code or perhaps that was >>> his intention to begin with, but maybe he thinks differently now (?). > >> I think it's more useful to keep as a bug catcher, although I do >> understand the thinking behind just having it be a no-op. > > Well, my thinking is that it helps nobody if call sites have to have > explicit workarounds for a totally-arbitrary refusal to handle edge > cases in the primitive functions. I do not think that is good software > design. If you want to have assertions that particular call sites are > specifying nonempty ranges, put those in the call sites where it's > important. But as-is, this seems like, say, defining foreach() to > blow up on an empty list. How about adding Asserts to that effect in partprune.c and execPartition.c where they're not present? These are the only two files where it's currently being used, given that it was invented only recently and exactly for use by the new pruning code. I updated the patch that I posted in the last email to add those Asserts. FWIW, I can see at least the guard against < 0 values in number of other bms_* functions, but I won't be the one to make a call one way or the other about whether to change bms_add_range() to cope with erroneous inputs. Thanks, Amit
-
Re: negative bitmapset member not allowed Error with partition pruning
David Rowley <david.rowley@2ndquadrant.com> — 2018-07-27T04:34:40Z
On 27 July 2018 at 15:14, Tom Lane <tgl@sss.pgh.pa.us> wrote: > David Rowley <david.rowley@2ndquadrant.com> writes: >> On 27 July 2018 at 13:35, Amit Langote <Langote_Amit_f8@lab.ntt.co.jp> wrote: >>> On 2018/07/27 1:28, Tom Lane wrote: >>>> (BTW, I'm not sure that it was wise to design bms_add_range to fail for >>>> empty ranges. Maybe it'd be better to redefine it as a no-op for >>>> upper < lower?) > >>> FWIW, I was thankful that David those left those checks there, because it >>> helped expose quite a few bugs when writing this code or perhaps that was >>> his intention to begin with, but maybe he thinks differently now (?). > >> I think it's more useful to keep as a bug catcher, although I do >> understand the thinking behind just having it be a no-op. > > Well, my thinking is that it helps nobody if call sites have to have > explicit workarounds for a totally-arbitrary refusal to handle edge > cases in the primitive functions. I do not think that is good software > design. If you want to have assertions that particular call sites are > specifying nonempty ranges, put those in the call sites where it's > important. But as-is, this seems like, say, defining foreach() to > blow up on an empty list. Okay, that's a fair point. I agree, adding Asserts at the current call sites seems better. -- David Rowley http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: negative bitmapset member not allowed Error with partition pruning
Alvaro Herrera <alvherre@2ndquadrant.com> — 2018-07-30T22:54:46Z
On 2018-Jul-27, David Rowley wrote: > On 27 July 2018 at 15:14, Tom Lane <tgl@sss.pgh.pa.us> wrote: > > Well, my thinking is that it helps nobody if call sites have to have > > explicit workarounds for a totally-arbitrary refusal to handle edge > > cases in the primitive functions. I do not think that is good software > > design. If you want to have assertions that particular call sites are > > specifying nonempty ranges, put those in the call sites where it's > > important. But as-is, this seems like, say, defining foreach() to > > blow up on an empty list. > > Okay, that's a fair point. I agree, adding Asserts at the current > call sites seems better. Given the discussion, I pushed two commits: first, bms_add_range returns the input bms if the range is empty, also adding Rajkumar's test case, which I also verified to reproduce the bug, and passes (for me) with the bms_add_range change. The second commit includes the proposed asserts, but not the change to avoid calling bms_add_range when the range is empty. Thanks! -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services