BUG #17972: Assert failed in pull_varattnos_walker() for view with subquery and security qual - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #17972: Assert failed in pull_varattnos_walker() for view with subquery and security qual
Date
Msg-id 17972-f422c094237847d0@postgresql.org
Whole thread Raw
Responses Re: BUG #17972: Assert failed in pull_varattnos_walker() for view with subquery and security qual  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      17972
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 16beta1
Operating system:   Ubuntu 22.04
Description:

The following script:
CREATE TABLE t1(a int);
CREATE VIEW v1 WITH (security_barrier = true) AS SELECT a FROM t1;
CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD UPDATE t1 SET a =
NEW.a WHERE a = OLD.a;
CREATE VIEW v2 WITH (security_barrier = true) AS SELECT a FROM v1 WHERE
EXISTS (SELECT 1);

UPDATE v2 SET a = 1;

leads to a failed assertion with the stack trace:
Core was generated by `postgres: law regression [local] UPDATE
                        '.
Program terminated with signal SIGABRT, Aborted.

warning: Section `.reg-xstate/3314281' in core file too small.
#0  __pthread_kill_implementation (no_tid=0, signo=6,
threadid=140289111025600) at ./nptl/pthread_kill.c:44
44      ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6,
threadid=140289111025600) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140289111025600) at
./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140289111025600, signo=signo@entry=6) at
./nptl/pthread_kill.c:89
#3  0x00007f9799eee476 in __GI_raise (sig=sig@entry=6) at
../sysdeps/posix/raise.c:26
#4  0x00007f9799ed47f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x000055e8c9bc9a29 in ExceptionalCondition (conditionName=0x55e8ca47ec40
"!IsA(node, Query)", 
    fileName=0x55e8ca47ebe0 "var.c", lineNumber=320) at assert.c:66
#6  0x000055e8c9045865 in pull_varattnos_walker (node=0x629000035da0,
context=0x7ffe3dfdd800) at var.c:320
#7  0x000055e8c8c194b1 in expression_tree_walker_impl (node=0x62d00006f3d0,

    walker=0x55e8c90454b9 <pull_varattnos_walker>, context=0x7ffe3dfdd800)
at nodeFuncs.c:2144
#8  0x000055e8c904587f in pull_varattnos_walker (node=0x62d00006f3d0,
context=0x7ffe3dfdd800) at var.c:322
#9  0x000055e8c9045410 in pull_varattnos (node=0x62d00006f3d0, varno=2,
varattnos=0x7ffe3dfdd8b0) at var.c:298
#10 0x000055e8c8da2da7 in remove_unused_subquery_outputs
(subquery=0x62d00006fa58, rel=0x625000006070, 
    extra_used_attrs=0x0) at allpaths.c:4105
#11 0x000055e8c8d98300 in set_subquery_pathlist (root=0x62500005b958,
rel=0x625000006070, rti=2, 
    rte=0x629000035c40) at allpaths.c:2626
#12 0x000055e8c8d8a008 in set_rel_size (root=0x62500005b958,
rel=0x625000006070, rti=2, rte=0x629000035c40)
    at allpaths.c:424
#13 0x000055e8c8d897a1 in set_base_rel_sizes (root=0x62500005b958) at
allpaths.c:325
#14 0x000055e8c8d8881b in make_one_rel (root=0x62500005b958,
joinlist=0x62d00006fe40) at allpaths.c:186
#15 0x000055e8c8eb5073 in query_planner (root=0x62500005b958, 
    qp_callback=0x55e8c8ed50b0 <standard_qp_callback>,
qp_extra=0x7ffe3dfddef0) at planmain.c:278
#16 0x000055e8c8ec3f10 in grouping_planner (root=0x62500005b958,
tuple_fraction=0) at planner.c:1493
#17 0x000055e8c8ec1574 in subquery_planner (glob=0x62d00006edf0,
parse=0x629000035740, parent_root=0x0, 
    hasRecursion=false, tuple_fraction=0) at planner.c:1062
#18 0x000055e8c8eb70a4 in standard_planner (parse=0x629000035740, 
    query_string=0x625000005218 "UPDATE v2 SET a = 1;", cursorOptions=2048,
boundParams=0x0) at planner.c:411
#19 0x000055e8c8eb5fd0 in planner (parse=0x629000035740,
query_string=0x625000005218 "UPDATE v2 SET a = 1;", 
    cursorOptions=2048, boundParams=0x0) at planner.c:281
#20 0x000055e8c945339e in pg_plan_query (querytree=0x629000035740, 
    query_string=0x625000005218 "UPDATE v2 SET a = 1;", cursorOptions=2048,
boundParams=0x0) at postgres.c:904
#21 0x000055e8c9453ca4 in pg_plan_queries (querytrees=0x62d00006e7c8, 
    query_string=0x625000005218 "UPDATE v2 SET a = 1;", cursorOptions=2048,
boundParams=0x0) at postgres.c:996
#22 0x000055e8c9454555 in exec_simple_query (query_string=0x625000005218
"UPDATE v2 SET a = 1;")
    at postgres.c:1193
#23 0x000055e8c9461e56 in PostgresMain (dbname=0x62900001b358 "regression",
username=0x6250000020f8 "law")
    at postgres.c:4632
#24 0x000055e8c90d449d in BackendRun (port=0x614000000440) at
postmaster.c:4461
#25 0x000055e8c90d2d23 in BackendStartup (port=0x614000000440) at
postmaster.c:4189
#26 0x000055e8c90c941d in ServerLoop () at postmaster.c:1779
#27 0x000055e8c90c7a05 in PostmasterMain (argc=3, argv=0x603000000670) at
postmaster.c:1463
#28 0x000055e8c8af536f in main (argc=3, argv=0x603000000670) at main.c:198

(gdb) frame 9
#9  0x000055e8c9045410 in pull_varattnos (node=0x62d00006f3d0, varno=2,
varattnos=0x7ffe3dfdd8b0) at var.c:298
298             (void) pull_varattnos_walker(node, &context);
(gdb) p *((SubLink *)node)->subselect
$1 = {type = T_Query}

(gdb) frame 12
#12 0x000055e8c8d8a008 in set_rel_size (root=0x62500005b958,
rel=0x625000006070, rti=2, rte=0x629000035c40)
    at allpaths.c:424
424                                     set_subquery_pathlist(root, rel,
rti, rte);
(gdb) p *(Query *)((SubLink *)((RestrictInfo
*)rel->baserestrictinfo->elements->ptr_value)->clause)->subselect
$2 = {type = T_Query, commandType = CMD_SELECT, querySource = QSRC_ORIGINAL,
...}

`git bisect` for this anomaly pointed at 215b43cdc.

It looks like the failure caused by the following:
1) For a securiy view, the rewriteTargetView() call sets securityQuals;
2) subquery_planner() sets root->qual_security_level = 1
 (Max(root->qual_security_level, list_length(rte->securityQuals)));
3) deconstruct_distribute() calls process_security_barrier_quals() ->
 distribute_qual_to_rels(), which performs
 "Add clause information to either the baserestrictinfo or joininfo list
...";
4) Later, when set_rel_size() called, for the case rel->rtekind ==
RTE_SUBQUERY
 we get set_subquery_pathlist() called, which in turn calls
 remove_unused_subquery_outputs(), where foreach(lc,
rel->baserestrictinfo)
 we have pull_varattnos() called with the clause->subselect having type
 T_QUERY, but a comment for pull_varattnos() says:
 * Currently, this does not support unplanned subqueries; that is not
needed
 * for current uses. ...
5) And we really stumble upon the Assert in pull_varattnos_walker().

IIIUC, 215b43cdc produced this failure due to
process_security_barrier_quals() added.


pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #17970: FEATURE REQUEST-allow re-adding GENERATED ALWAYS AS constraint to existing columns after removing it
Next
From: Tom Lane
Date:
Subject: Re: BUG #17972: Assert failed in pull_varattnos_walker() for view with subquery and security qual