pg.ddx.io pgsql-bugs@postgresql.org mailing list archive
help / color / mirror / Atom feedBUG #17826: An assert failed in /src/backend/optimizer/util/var.c
10+ messages / 3 participants
[nested] [flat]
Commits from this thread:
2023-03-17 eb7d043c9b 371e3daaa5 Fix incorrect logic for determining safe WindowAgg run conditions
* BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
@ 2023-03-09 09:10 PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 10+ messages in thread
From: PG Bug reporting form @ 2023-03-09 09:10 UTC (permalink / raw)
To: pgsql-bugs@lists.postgresql.org; +Cc: xinwen@stu.scu.edu.cn
The following bug has been logged on the website:
Bug reference: 17826
Logged by: Anban Company
Email address: xinwen@stu.scu.edu.cn
PostgreSQL version: 15.2
Operating system: Ubuntu 20.04
Description:
When executing the following query:
WITH table1 AS ( SELECT 1 ) SELECT 1 FROM ( SELECT RANK ( ) OVER ( ) column0
FROM table1 JOIN table1 AS alias0 ON TRUE ) AS alias1 WHERE ( CASE WHEN ( 1
IN ( SELECT 1 ) ) THEN 1 END = column0 ) ;
I get a failed assertion with the following stacktrace:
Core was generated by `postgres: postgres postgres [local] SELECT
'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007f68a29b6859 in __GI_abort () at abort.c:79
#2 0x0000555d7a2db598 in ExceptionalCondition
(conditionName=conditionName@entry=0x555d7a44c828 "!IsA(node, SubPlan)",
errorType=errorType@entry=0x555d7a3394a0 "FailedAssertion",
fileName=fileName@entry=0x555d7a4504b8
"/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/util/var.c",
lineNumber=lineNumber@entry=872) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/utils/error/assert.c:69
#3 0x0000555d7a105c41 in flatten_join_alias_vars_mutator
(node=0x555d7aa0f518, context=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/util/var.c:872
#4 0x0000555d7a08cba9 in expression_tree_mutator (node=0x555d7aa07eb0,
mutator=0x555d7a1057a0 <flatten_join_alias_vars_mutator>,
context=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/nodes/nodeFuncs.c:3320
#5 0x0000555d7a08cff6 in expression_tree_mutator (node=0x555d7aa0f888,
mutator=0x555d7a1057a0 <flatten_join_alias_vars_mutator>,
context=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/nodes/nodeFuncs.c:3165
#6 0x0000555d7a08cef9 in expression_tree_mutator (node=0x555d7aa07e58,
mutator=0x555d7a1057a0 <flatten_join_alias_vars_mutator>,
context=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/nodes/nodeFuncs.c:3137
#7 0x0000555d7a08cff6 in expression_tree_mutator (node=0x555d7aa11ba0,
mutator=0x555d7a1057a0 <flatten_join_alias_vars_mutator>,
context=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/nodes/nodeFuncs.c:3165
#8 0x0000555d7a08ccab in expression_tree_mutator (node=0x555d7aa11400,
mutator=0x555d7a1057a0 <flatten_join_alias_vars_mutator>,
context=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/nodes/nodeFuncs.c:2780
#9 0x0000555d7a08cff6 in expression_tree_mutator (node=0x555d7aa11bf8,
mutator=mutator@entry=0x555d7a1057a0 <flatten_join_alias_vars_mutator>,
context=context@entry=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/nodes/nodeFuncs.c:3165
#10 0x0000555d7a105821 in flatten_join_alias_vars_mutator (node=<optimized
out>, context=context@entry=0x7fff50b0c980) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/util/var.c:878
#11 0x0000555d7a10602e in flatten_join_alias_vars (query=<optimized out>,
node=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/util/var.c:744
#12 0x0000555d7a0d4b79 in preprocess_expression
(root=root@entry=0x555d7aa11ca8, expr=<optimized out>, kind=kind@entry=1) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/plan/planner.c:1105
#13 0x0000555d7a0dcb8c in subquery_planner (glob=<optimized out>,
parse=parse@entry=0x555d7aa10058,
parent_root=parent_root@entry=0x555d7aa05f78,
hasRecursion=hasRecursion@entry=false, tuple_fraction=0) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/plan/planner.c:829
#14 0x0000555d7a0ac11e in set_subquery_pathlist (rte=<optimized out>,
rti=<optimized out>, rel=<optimized out>, root=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/path/allpaths.c:2601
#15 set_rel_size (root=<optimized out>, rel=<optimized out>, rti=<optimized
out>, rte=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/path/allpaths.c:425
#16 0x0000555d7a0ae980 in set_base_rel_sizes (root=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/path/allpaths.c:326
#17 make_one_rel (root=root@entry=0x555d7aa05f78,
joinlist=joinlist@entry=0x555d7aa0fe18) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/path/allpaths.c:188
#18 0x0000555d7a0d4976 in query_planner (root=root@entry=0x555d7aa05f78,
qp_callback=qp_callback@entry=0x555d7a0d5990 <standard_qp_callback>,
qp_extra=qp_extra@entry=0x7fff50b0ccb0) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/plan/planmain.c:276
#19 0x0000555d7a0da4f9 in grouping_planner (root=<optimized out>,
tuple_fraction=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/plan/planner.c:1470
#20 0x0000555d7a0dd145 in subquery_planner (glob=glob@entry=0x555d7aa047d8,
parse=parse@entry=0x555d7aa02e98, parent_root=parent_root@entry=0x0,
hasRecursion=hasRecursion@entry=false,
tuple_fraction=tuple_fraction@entry=0) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/plan/planner.c:1047
#21 0x0000555d7a0dd5a3 in standard_planner (parse=0x555d7aa02e98,
query_string=<optimized out>, cursorOptions=2048, boundParams=<optimized
out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/optimizer/plan/planner.c:406
#22 0x0000555d7a1af74c in pg_plan_query (querytree=0x555d7aa02e98,
query_string=0x555d7a93c010 "WITH table1 AS ( SELECT 1 ) SELECT 1 FROM (
SELECT RANK ( ) OVER ( ) column46 FROM table1 JOIN table1 AS alias0 ON TRUE
) AS alias1 WHERE ( CASE WHEN ( 1 IN ( SELECT 1 ) ) THEN 1 END = column46 )
;", cursorOptions=2048, boundParams=0x0) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/tcop/postgres.c:883
#23 0x0000555d7a1af841 in pg_plan_queries (querytrees=0x555d7aa05f20,
query_string=query_string@entry=0x555d7a93c010 "WITH table1 AS ( SELECT 1 )
SELECT 1 FROM ( SELECT RANK ( ) OVER ( ) column46 FROM table1 JOIN table1 AS
alias0 ON TRUE ) AS alias1 WHERE ( CASE WHEN ( 1 IN ( SELECT 1 ) ) THEN 1
END = column46 ) ;", cursorOptions=cursorOptions@entry=2048,
boundParams=boundParams@entry=0x0) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/tcop/postgres.c:975
#24 0x0000555d7a1afc4f in exec_simple_query ( query_string=0x555d7a93c010
"WITH table1 AS ( SELECT 1 ) SELECT 1 FROM ( SELECT RANK ( ) OVER ( )
column46 FROM table1 JOIN table1 AS alias0 ON TRUE ) AS alias1 WHERE ( CASE
WHEN ( 1 IN ( SELECT 1 ) ) THEN 1 END = column46 ) ;") at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/tcop/postgres.c:1169
#25 0x0000555d7a1b17fc in PostgresMain (dbname=<optimized out>,
username=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/tcop/postgres.c:4593
#26 0x0000555d7a11e5aa in BackendRun (port=<optimized out>, port=<optimized
out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/postmaster/postmaster.c:4511
#27 BackendStartup (port=<optimized out>) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/postmaster/postmaster.c:4239
#28 ServerLoop () at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/postmaster/postmaster.c:1806
#29 0x0000555d7a11f71b in PostmasterMain (argc=<optimized out>,
argv=0x555d7a936310) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/postmaster/postmaster.c:1478
#30 0x0000555d79e49510 in main (argc=3, argv=0x555d7a936310) at
/home/postgres/postgresql-15.2/original_bin-15.2/../src/backend/main/main.c:202
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
@ 2023-03-09 16:09 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
0 siblings, 1 reply; 10+ messages in thread
From: Tom Lane @ 2023-03-09 16:09 UTC (permalink / raw)
To: xinwen@stu.scu.edu.cn; +Cc: pgsql-bugs@lists.postgresql.org, David Rowley <dgrowleyml@gmail.com>
PG Bug reporting form <noreply@postgresql.org> writes:
> When executing the following query:
> WITH table1 AS ( SELECT 1 ) SELECT 1 FROM ( SELECT RANK ( ) OVER ( ) column0
> FROM table1 JOIN table1 AS alias0 ON TRUE ) AS alias1 WHERE ( CASE WHEN ( 1
> IN ( SELECT 1 ) ) THEN 1 END = column0 ) ;
> I get a failed assertion with the following stacktrace:
The assertion is complaining about a SubPlan that has gotten pushed down
into the subquery, where it should not have been. Tracing through it,
the blame appears to fall on commit 9d9c02ccd, which added this rather
astonishing bit of coding:
if (!rinfo->pseudoconstant &&
qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo))
{
/* Push it down */
subquery_push_qual(subquery, rte, rti, clause);
}
else
{
+ /*
+ * Since we can't push the qual down into the subquery, check
+ * if it happens to reference a window function. If so then
+ * it might be useful to use for the WindowAgg's runCondition.
+ */
+ if (!subquery->hasWindowFuncs ||
+ check_and_push_window_quals(subquery, rte, rti, clause,
+ &run_cond_attrs))
In other words, after qual_is_pushdown_safe has rejected a qual as being
unsafe to push down, check_and_push_window_quals merrily does it anyway,
apparently on the theory that window functions are exempt from all rules.
How is this even a little bit sane?
We could fix the given problem by adding a duplicative contain_subplans
check in check_and_push_window_quals, but first I want to see an argument
why it's okay to ignore any of the other things qual_is_pushdown_safe is
checking for, because I think this is dangerously broken on every single
count. My druthers would be to remove check_and_push_window_quals
altogether.
regards, tom lane
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
@ 2023-03-11 06:35 ` David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 10+ messages in thread
From: David Rowley @ 2023-03-11 06:35 UTC (permalink / raw)
To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
On Fri, 10 Mar 2023 at 05:09, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> In other words, after qual_is_pushdown_safe has rejected a qual as being
> unsafe to push down, check_and_push_window_quals merrily does it anyway,
> apparently on the theory that window functions are exempt from all rules.
> How is this even a little bit sane?
I don't think it is. I've not looked in detail yet, but I think we
might be able to do something in check_output_expressions() so that we
track the targetIsInAllPartitionLists() separately. Maybe
unsafeColumns[] needs to become an enum type that has UNSAFE, SAFE,
WINDOW_RUNCONDITION_ONLY and then change things so we never make a
runCondition when the qual is UNSAFE.
Anyway, I'll give it more thought and aim to come up with a patch
early next week.
David
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
@ 2023-03-11 17:23 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
0 siblings, 1 reply; 10+ messages in thread
From: Tom Lane @ 2023-03-11 17:23 UTC (permalink / raw)
To: David Rowley <dgrowleyml@gmail.com>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
David Rowley <dgrowleyml@gmail.com> writes:
> On Fri, 10 Mar 2023 at 05:09, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> How is this even a little bit sane?
> I don't think it is. I've not looked in detail yet, but I think we
> might be able to do something in check_output_expressions() so that we
> track the targetIsInAllPartitionLists() separately. Maybe
> unsafeColumns[] needs to become an enum type that has UNSAFE, SAFE,
> WINDOW_RUNCONDITION_ONLY and then change things so we never make a
> runCondition when the qual is UNSAFE.
> Anyway, I'll give it more thought and aim to come up with a patch
> early next week.
Why can't we simply *remove* all this logic from subquery pushdown?
I would expect that what happens in useful cases is that we push down
the (safe) qual and then during planning of the subquery we see a WHERE
clause matching the window run condition and work with that. So this
all seems redundant, quite aside from being faulty.
regards, tom lane
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
@ 2023-03-12 21:19 ` David Rowley <dgrowleyml@gmail.com>
2023-03-12 21:43 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 10+ messages in thread
From: David Rowley @ 2023-03-12 21:19 UTC (permalink / raw)
To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
On Sun, 12 Mar 2023 at 06:24, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Why can't we simply *remove* all this logic from subquery pushdown?
>
> I would expect that what happens in useful cases is that we push down
> the (safe) qual and then during planning of the subquery we see a WHERE
> clause matching the window run condition and work with that. So this
> all seems redundant, quite aside from being faulty.
hmm, sorry, I can't quite make sense of that.
It is only possible to either leave such quals in the outer query in
the WHERE clause or make them run conditions of some WindowClause in
the subquery. They can never be legally in the WHERE clause of the
subquery as window functions cannot be evaluated in the WHERE clause.
So I'm not really sure what the point of temporarily putting it in the
subqueries WHERE clause would be if we just later unconditionally move
it to become a WindowClause run condition. If we're pushing it down,
then we need to validate that the qual definitely can become a run
condition qual, why not just make it that when it passes the
validation?
David
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
@ 2023-03-12 21:43 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-14 11:13 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
0 siblings, 1 reply; 10+ messages in thread
From: Tom Lane @ 2023-03-12 21:43 UTC (permalink / raw)
To: David Rowley <dgrowleyml@gmail.com>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
David Rowley <dgrowleyml@gmail.com> writes:
> It is only possible to either leave such quals in the outer query in
> the WHERE clause or make them run conditions of some WindowClause in
> the subquery. They can never be legally in the WHERE clause of the
> subquery as window functions cannot be evaluated in the WHERE clause.
Ah, got it. So basically, the quals that we want are excluded by
check_output_expressions' point 4 (since they reference window
function output columns rather than partitioning columns). I think
we need them to satisfy every other property that's checked in this
code, though. Now I agree that we need to refactor a bit -- we
don't want to have to re-check all of these conditions.
regards, tom lane
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-12 21:43 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
@ 2023-03-14 11:13 ` David Rowley <dgrowleyml@gmail.com>
2023-03-16 18:59 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 10+ messages in thread
From: David Rowley @ 2023-03-14 11:13 UTC (permalink / raw)
To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
On Mon, 13 Mar 2023 at 10:43, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> David Rowley <dgrowleyml@gmail.com> writes:
> > It is only possible to either leave such quals in the outer query in
> > the WHERE clause or make them run conditions of some WindowClause in
> > the subquery. They can never be legally in the WHERE clause of the
> > subquery as window functions cannot be evaluated in the WHERE clause.
>
> Ah, got it. So basically, the quals that we want are excluded by
> check_output_expressions' point 4 (since they reference window
> function output columns rather than partitioning columns). I think
> we need them to satisfy every other property that's checked in this
> code, though. Now I agree that we need to refactor a bit -- we
> don't want to have to re-check all of these conditions.
OK, patch attached.
I've coded it so the only safety hazard that we can ignore for run
conditions is the column is in all WindowClause PARTITION BYs. I
believe the DISTINCT ON column not in the sort list is still a hazard.
The attached also fixes the issue with making a run condition when the
window func contains a volatile func, e.g:
explain select * from (select oid,count(random()) over (order by oid)
c from pg_class) c where c < 10;
I think this is ok to back patch to v15 as the pushdown_safety_info
struct is static. I think it'd be ok to widen that type to int
instead of unsigned char, I just didn't.
I probably need to do a bit more indenting work. I'll look again tomorrow.
David
Attachments:
fix_safety_hazard_in_runcondition_qual_pushdown.patch (application/octet-stream, 13.6K) download
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 479a694bca..6e8aa10a9c 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -52,14 +52,29 @@
#include "utils/lsyscache.h"
+/* Bitmask flags for pushdown_safety_info.safetyFlags */
+#define TARGET_HAS_VOLATILE_FUNC (1 << 0)
+#define TARGET_HAS_SET_FUNC (1 << 1)
+#define TARGET_NOTIN_DISTINCTON_CLAUSE (1 << 2)
+#define TARGET_NOTIN_PARTITIONBY_CLAUSE (1 << 3)
+#define TARGET_TYPE_MISMATCH (1 << 4)
+
/* results of subquery_is_pushdown_safe */
typedef struct pushdown_safety_info
{
- bool *unsafeColumns; /* which output columns are unsafe to use */
+ unsigned char *safetyFlags; /* bitmask flags for output columns */
bool unsafeVolatile; /* don't push down volatile quals */
bool unsafeLeaky; /* don't push down leaky quals */
} pushdown_safety_info;
+typedef enum pushdown_safe_type
+{
+ pushdown_unsafe, /* unsafe to push qual into subquery */
+ pushdown_safe, /* safe to push qual into subquery */
+ pushdown_windowclause_runcond /* unsafe, but may work as WindowClause run
+ * condition */
+} pushdown_safe_type;
+
/* These parameters are set by GUC */
bool enable_geqo = false; /* just in case GUC doesn't set it */
int geqo_threshold;
@@ -136,9 +151,9 @@ static void check_output_expressions(Query *subquery,
static void compare_tlist_datatypes(List *tlist, List *colTypes,
pushdown_safety_info *safetyInfo);
static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query);
-static bool qual_is_pushdown_safe(Query *subquery, Index rti,
- RestrictInfo *rinfo,
- pushdown_safety_info *safetyInfo);
+static pushdown_safe_type qual_is_pushdown_safe(Query *subquery, Index rti,
+ RestrictInfo *rinfo,
+ pushdown_safety_info *safetyInfo);
static void subquery_push_qual(Query *subquery,
RangeTblEntry *rte, Index rti, Node *qual);
static void recurse_push_qual(Node *setOp, Query *topquery,
@@ -2500,13 +2515,14 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
/*
* Zero out result area for subquery_is_pushdown_safe, so that it can set
* flags as needed while recursing. In particular, we need a workspace
- * for keeping track of unsafe-to-reference columns. unsafeColumns[i]
- * will be set true if we find that output column i of the subquery is
- * unsafe to use in a pushed-down qual.
+ * for keeping track of the reasons why a qual is unsafe to push down.
+ * These reasons are stored in the bits inside safetyFlags[i] when we
+ * discover reasons that column i of the subquery is unsafe to be used as
+ * a pushed-down qual.
*/
memset(&safetyInfo, 0, sizeof(safetyInfo));
- safetyInfo.unsafeColumns = (bool *)
- palloc0((list_length(subquery->targetList) + 1) * sizeof(bool));
+ safetyInfo.safetyFlags = (unsigned char *)
+ palloc0((list_length(subquery->targetList) + 1) * sizeof(unsigned char));
/*
* If the subquery has the "security_barrier" flag, it means the subquery
@@ -2549,29 +2565,37 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
Node *clause = (Node *) rinfo->clause;
- if (!rinfo->pseudoconstant &&
- qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo))
+ if (!rinfo->pseudoconstant)
{
- /* Push it down */
- subquery_push_qual(subquery, rte, rti, clause);
- }
- else
- {
- /*
- * Since we can't push the qual down into the subquery, check
- * if it happens to reference a window function. If so then
- * it might be useful to use for the WindowAgg's runCondition.
- */
- if (!subquery->hasWindowFuncs ||
- check_and_push_window_quals(subquery, rte, rti, clause,
- &run_cond_attrs))
+ switch (qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo))
{
- /*
- * subquery has no window funcs or the clause is not a
- * suitable window run condition qual or it is, but the
- * original must also be kept in the upper query.
- */
- upperrestrictlist = lappend(upperrestrictlist, rinfo);
+ case pushdown_safe:
+ /* Push it down */
+ subquery_push_qual(subquery, rte, rti, clause);
+ break;
+
+ case pushdown_windowclause_runcond:
+ /*
+ * Since we can't push the qual down into the subquery, check
+ * if it happens to reference a window function. If so then
+ * it might be useful to use for the WindowAgg's runCondition.
+ */
+ if (!subquery->hasWindowFuncs ||
+ check_and_push_window_quals(subquery, rte, rti, clause,
+ &run_cond_attrs))
+ {
+ /*
+ * subquery has no window funcs or the clause is not a
+ * suitable window run condition qual or it is, but the
+ * original must also be kept in the upper query.
+ */
+ upperrestrictlist = lappend(upperrestrictlist, rinfo);
+ }
+ break;
+
+ case pushdown_unsafe:
+ upperrestrictlist = lappend(upperrestrictlist, rinfo);
+ break;
}
}
}
@@ -2579,7 +2603,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
/* We don't bother recomputing baserestrict_min_security */
}
- pfree(safetyInfo.unsafeColumns);
+ pfree(safetyInfo.safetyFlags);
/*
* The upper query might not use all the subquery's output columns; if
@@ -3517,13 +3541,13 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
*
* In addition, we make several checks on the subquery's output columns to see
* if it is safe to reference them in pushed-down quals. If output column k
- * is found to be unsafe to reference, we set safetyInfo->unsafeColumns[k]
- * to true, but we don't reject the subquery overall since column k might not
- * be referenced by some/all quals. The unsafeColumns[] array will be
- * consulted later by qual_is_pushdown_safe(). It's better to do it this way
- * than to make the checks directly in qual_is_pushdown_safe(), because when
- * the subquery involves set operations we have to check the output
- * expressions in each arm of the set op.
+ * is found to be unsafe to reference, we set the reason for that inside
+ * safetyInfo->safetyFlags[k], but we don't reject the subquery overall since
+ * column k might not be referenced by some/all quals. The safetyFlags[]
+ * array will be consulted later by qual_is_pushdown_safe(). It's better to
+ * do it this way than to make the checks directly in qual_is_pushdown_safe(),
+ * because when the subquery involves set operations we have to check the
+ * output expressions in each arm of the set op.
*
* Note: pushing quals into a DISTINCT subquery is theoretically dubious:
* we're effectively assuming that the quals cannot distinguish values that
@@ -3571,9 +3595,9 @@ subquery_is_pushdown_safe(Query *subquery, Query *topquery,
/*
* If we're at a leaf query, check for unsafe expressions in its target
- * list, and mark any unsafe ones in unsafeColumns[]. (Non-leaf nodes in
- * setop trees have only simple Vars in their tlists, so no need to check
- * them.)
+ * list, and mark the reasons why they're unsafe in safetyFlags[].
+ * (Non-leaf nodes in setop trees have only simple Vars in their tlists,
+ * so no need to check them.)
*/
if (subquery->setOperations == NULL)
check_output_expressions(subquery, safetyInfo);
@@ -3644,9 +3668,9 @@ recurse_pushdown_safe(Node *setOp, Query *topquery,
*
* There are several cases in which it's unsafe to push down an upper-level
* qual if it references a particular output column of a subquery. We check
- * each output column of the subquery and set unsafeColumns[k] to true if
- * that column is unsafe for a pushed-down qual to reference. The conditions
- * checked here are:
+ * each output column of the subquery and set flags in safetyFlags[k] when we
+ * see that column is unsafe for a pushed-down qual to reference. The
+ * conditions checked here are:
*
* 1. We must not push down any quals that refer to subselect outputs that
* return sets, else we'd introduce functions-returning-sets into the
@@ -3684,40 +3708,40 @@ check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo)
if (tle->resjunk)
continue; /* ignore resjunk columns */
- /* We need not check further if output col is already known unsafe */
- if (safetyInfo->unsafeColumns[tle->resno])
- continue;
-
/* Functions returning sets are unsafe (point 1) */
if (subquery->hasTargetSRFs &&
+ (safetyInfo->safetyFlags[tle->resno] & TARGET_HAS_SET_FUNC) == 0 &&
expression_returns_set((Node *) tle->expr))
{
- safetyInfo->unsafeColumns[tle->resno] = true;
+ safetyInfo->safetyFlags[tle->resno] |= TARGET_HAS_SET_FUNC;
continue;
}
/* Volatile functions are unsafe (point 2) */
- if (contain_volatile_functions((Node *) tle->expr))
+ if ((safetyInfo->safetyFlags[tle->resno] & TARGET_HAS_VOLATILE_FUNC) == 0 &&
+ contain_volatile_functions((Node *) tle->expr))
{
- safetyInfo->unsafeColumns[tle->resno] = true;
+ safetyInfo->safetyFlags[tle->resno] |= TARGET_HAS_VOLATILE_FUNC;
continue;
}
/* If subquery uses DISTINCT ON, check point 3 */
if (subquery->hasDistinctOn &&
+ (safetyInfo->safetyFlags[tle->resno] & TARGET_NOTIN_DISTINCTON_CLAUSE) == 0 &&
!targetIsInSortList(tle, InvalidOid, subquery->distinctClause))
{
/* non-DISTINCT column, so mark it unsafe */
- safetyInfo->unsafeColumns[tle->resno] = true;
+ safetyInfo->safetyFlags[tle->resno] |= TARGET_NOTIN_DISTINCTON_CLAUSE;
continue;
}
/* If subquery uses window functions, check point 4 */
if (subquery->hasWindowFuncs &&
+ (safetyInfo->safetyFlags[tle->resno] & TARGET_NOTIN_DISTINCTON_CLAUSE) == 0 &&
!targetIsInAllPartitionLists(tle, subquery))
{
/* not present in all PARTITION BY clauses, so mark it unsafe */
- safetyInfo->unsafeColumns[tle->resno] = true;
+ safetyInfo->safetyFlags[tle->resno] |= TARGET_NOTIN_PARTITIONBY_CLAUSE;
continue;
}
}
@@ -3729,8 +3753,8 @@ check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo)
* subquery columns that suffer no type coercions in the set operation.
* Otherwise there are possible semantic gotchas. So, we check the
* component queries to see if any of them have output types different from
- * the top-level setop outputs. unsafeColumns[k] is set true if column k
- * has different type in any component.
+ * the top-level setop outputs. We set the TARGET_TYPE_MISMATCH bit in
+ * safetyFlags[k] if column k has different type in any component.
*
* We don't have to care about typmods here: the only allowed difference
* between set-op input and output typmods is input is a specific typmod
@@ -3738,7 +3762,7 @@ check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo)
*
* tlist is a subquery tlist.
* colTypes is an OID list of the top-level setop's output column types.
- * safetyInfo->unsafeColumns[] is the result array.
+ * safetyInfo is the pushdown_safety_info to set safetyFlags[] for.
*/
static void
compare_tlist_datatypes(List *tlist, List *colTypes,
@@ -3756,7 +3780,7 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
if (colType == NULL)
elog(ERROR, "wrong number of tlist entries");
if (exprType((Node *) tle->expr) != lfirst_oid(colType))
- safetyInfo->unsafeColumns[tle->resno] = true;
+ safetyInfo->safetyFlags[tle->resno] |= TARGET_TYPE_MISMATCH;
colType = lnext(colTypes, colType);
}
if (colType != NULL)
@@ -3816,28 +3840,28 @@ targetIsInAllPartitionLists(TargetEntry *tle, Query *query)
* 5. rinfo's clause must not refer to any subquery output columns that were
* found to be unsafe to reference by subquery_is_pushdown_safe().
*/
-static bool
+static pushdown_safe_type
qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
pushdown_safety_info *safetyInfo)
{
- bool safe = true;
+ pushdown_safe_type safe = pushdown_safe;
Node *qual = (Node *) rinfo->clause;
List *vars;
ListCell *vl;
/* Refuse subselects (point 1) */
if (contain_subplans(qual))
- return false;
+ return pushdown_unsafe;
/* Refuse volatile quals if we found they'd be unsafe (point 2) */
if (safetyInfo->unsafeVolatile &&
contain_volatile_functions((Node *) rinfo))
- return false;
+ return pushdown_unsafe;
/* Refuse leaky quals if told to (point 3) */
if (safetyInfo->unsafeLeaky &&
contain_leaked_vars(qual))
- return false;
+ return pushdown_unsafe;
/*
* It would be unsafe to push down window function calls, but at least for
@@ -3866,7 +3890,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
*/
if (!IsA(var, Var))
{
- safe = false;
+ safe = pushdown_unsafe;
break;
}
@@ -3878,7 +3902,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
*/
if (var->varno != rti)
{
- safe = false;
+ safe = pushdown_unsafe;
break;
}
@@ -3888,15 +3912,26 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
/* Check point 4 */
if (var->varattno == 0)
{
- safe = false;
+ safe = pushdown_unsafe;
break;
}
/* Check point 5 */
- if (safetyInfo->unsafeColumns[var->varattno])
+ if (safetyInfo->safetyFlags[var->varattno] != 0)
{
- safe = false;
- break;
+ if (safetyInfo->safetyFlags[var->varattno] &
+ (TARGET_HAS_VOLATILE_FUNC|TARGET_HAS_SET_FUNC|
+ TARGET_NOTIN_DISTINCTON_CLAUSE|TARGET_TYPE_MISMATCH))
+ {
+ safe = pushdown_unsafe;
+ break;
+ }
+ else
+ {
+ /* TARGET_NOTIN_PARTITIONBY_CLAUSE is ok for run conditions */
+ safe = pushdown_windowclause_runcond;
+ /* don't break, we might find another Var to be unsafe */
+ }
}
}
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-12 21:43 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-14 11:13 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
@ 2023-03-16 18:59 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-17 03:11 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
0 siblings, 1 reply; 10+ messages in thread
From: Tom Lane @ 2023-03-16 18:59 UTC (permalink / raw)
To: David Rowley <dgrowleyml@gmail.com>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
David Rowley <dgrowleyml@gmail.com> writes:
> On Mon, 13 Mar 2023 at 10:43, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Ah, got it. So basically, the quals that we want are excluded by
>> check_output_expressions' point 4 (since they reference window
>> function output columns rather than partitioning columns). I think
>> we need them to satisfy every other property that's checked in this
>> code, though. Now I agree that we need to refactor a bit -- we
>> don't want to have to re-check all of these conditions.
> OK, patch attached.
This looks good to me. As a matter of style, I'd capitalize the
enum constant names, but I think it's OK otherwise.
> I probably need to do a bit more indenting work. I'll look again tomorrow.
Yeah, this looks like pgindent might not like it as-is.
regards, tom lane
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-12 21:43 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-14 11:13 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-16 18:59 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
@ 2023-03-17 03:11 ` David Rowley <dgrowleyml@gmail.com>
2023-03-17 03:34 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 10+ messages in thread
From: David Rowley @ 2023-03-17 03:11 UTC (permalink / raw)
To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
On Fri, 17 Mar 2023 at 07:59, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> David Rowley <dgrowleyml@gmail.com> writes:
> > OK, patch attached.
>
> This looks good to me. As a matter of style, I'd capitalize the
> enum constant names, but I think it's OK otherwise.
Thanks. I had been doing a bit more work on it and it looks very
slightly different from when you saw it. Agreed with the capitals in
the enum values.
I also found had to disallow subqueries in the WindowFunc. That
required a subplan check inside find_window_run_conditions().
I kinda also wanted to do the attached so that the logic to push or
not to push was more centralised. I just couldn't figure out exactly
why we don't push down pseudoconstant quals, therefore, was unable to
document that sufficiently in the header comment in
qual_is_pushdown_safe(). I thought we might as well talk about that
while on the topic as what I've just committed does not really take
any measures to explain it.
The attached patch is graded for the assistance of discussion only.
David
Attachments:
slightly_neater_qual_is_pushdown_safe.patch (application/octet-stream, 3.4K) download
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 244957a248..8c5ff52564 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -2572,12 +2572,6 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
Node *clause = (Node *) rinfo->clause;
- if (rinfo->pseudoconstant)
- {
- upperrestrictlist = lappend(upperrestrictlist, rinfo);
- continue;
- }
-
switch (qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo))
{
case PUSHDOWN_SAFE:
@@ -3838,24 +3832,26 @@ targetIsInAllPartitionLists(TargetEntry *tle, Query *query)
*
* Conditions checked here:
*
- * 1. rinfo's clause must not contain any SubPlans (mainly because it's
+ * 1. rinfo must not be a pseudoconstant, because... XXX fill in reason.
+ *
+ * 2. rinfo's clause must not contain any SubPlans (mainly because it's
* unclear that it will work correctly: SubLinks will already have been
* transformed into SubPlans in the qual, but not in the subquery). Note that
* SubLinks that transform to initplans are safe, and will be accepted here
* because what we'll see in the qual is just a Param referencing the initplan
* output.
*
- * 2. If unsafeVolatile is set, rinfo's clause must not contain any volatile
+ * 3. If unsafeVolatile is set, rinfo's clause must not contain any volatile
* functions.
*
- * 3. If unsafeLeaky is set, rinfo's clause must not contain any leaky
+ * 4. If unsafeLeaky is set, rinfo's clause must not contain any leaky
* functions that are passed Var nodes, and therefore might reveal values from
* the subquery as side effects.
*
- * 4. rinfo's clause must not refer to the whole-row output of the subquery
+ * 5. rinfo's clause must not refer to the whole-row output of the subquery
* (since there is no easy way to name that within the subquery itself).
*
- * 5. rinfo's clause must not refer to any subquery output columns that were
+ * 6. rinfo's clause must not refer to any subquery output columns that were
* found to be unsafe to reference by subquery_is_pushdown_safe().
*/
static pushdown_safe_type
@@ -3867,16 +3863,20 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
List *vars;
ListCell *vl;
- /* Refuse subselects (point 1) */
+ /* Refuse pseudoconstant (point 1) */
+ if (rinfo->pseudoconstant)
+ return PUSHDOWN_UNSAFE;
+
+ /* Refuse subselects (point 2) */
if (contain_subplans(qual))
return PUSHDOWN_UNSAFE;
- /* Refuse volatile quals if we found they'd be unsafe (point 2) */
+ /* Refuse volatile quals if we found they'd be unsafe (point 3) */
if (safetyInfo->unsafeVolatile &&
contain_volatile_functions((Node *) rinfo))
return PUSHDOWN_UNSAFE;
- /* Refuse leaky quals if told to (point 3) */
+ /* Refuse leaky quals if told to (point 4) */
if (safetyInfo->unsafeLeaky &&
contain_leaked_vars(qual))
return PUSHDOWN_UNSAFE;
@@ -3925,14 +3925,14 @@ qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
/* Subqueries have no system columns */
Assert(var->varattno >= 0);
- /* Check point 4 */
+ /* Check point 5 */
if (var->varattno == 0)
{
safe = PUSHDOWN_UNSAFE;
break;
}
- /* Check point 5 */
+ /* Check point 6 */
if (safetyInfo->unsafeFlags[var->varattno] != 0)
{
if (safetyInfo->unsafeFlags[var->varattno] &
^ permalink raw reply [nested|flat] 10+ messages in thread
* Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-12 21:43 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-14 11:13 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
2023-03-16 18:59 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c Tom Lane <tgl@sss.pgh.pa.us>
2023-03-17 03:11 ` Re: BUG #17826: An assert failed in /src/backend/optimizer/util/var.c David Rowley <dgrowleyml@gmail.com>
@ 2023-03-17 03:34 ` Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 0 replies; 10+ messages in thread
From: Tom Lane @ 2023-03-17 03:34 UTC (permalink / raw)
To: David Rowley <dgrowleyml@gmail.com>; +Cc: xinwen@stu.scu.edu.cn; pgsql-bugs@lists.postgresql.org
David Rowley <dgrowleyml@gmail.com> writes:
> I kinda also wanted to do the attached so that the logic to push or
> not to push was more centralised. I just couldn't figure out exactly
> why we don't push down pseudoconstant quals, therefore, was unable to
> document that sufficiently in the header comment in
> qual_is_pushdown_safe().
A pseudoconstant qual turns into a filtering Result node with a one-time
condition that controls whether it runs the child plan at all. You want
to put those as high in the plan tree as possible, so that they cut off
the maximum possible amount of work when the one-time condition is false.
So pushing one down into a subplan would be downright counterproductive.
regards, tom lane
^ permalink raw reply [nested|flat] 10+ messages in thread
end of thread, other threads:[~2023-03-17 03:34 UTC | newest]
Thread overview: 10+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2023-03-09 09:10 BUG #17826: An assert failed in /src/backend/optimizer/util/var.c PG Bug reporting form <noreply@postgresql.org>
2023-03-09 16:09 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-11 06:35 ` David Rowley <dgrowleyml@gmail.com>
2023-03-11 17:23 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-12 21:19 ` David Rowley <dgrowleyml@gmail.com>
2023-03-12 21:43 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-14 11:13 ` David Rowley <dgrowleyml@gmail.com>
2023-03-16 18:59 ` Tom Lane <tgl@sss.pgh.pa.us>
2023-03-17 03:11 ` David Rowley <dgrowleyml@gmail.com>
2023-03-17 03:34 ` Tom Lane <tgl@sss.pgh.pa.us>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox