29
29
#include "optimizer/pathnode.h"
30
30
#include "optimizer/paths.h"
31
31
#include "optimizer/planmain.h"
32
+ #include "optimizer/restrictinfo.h"
32
33
#include "optimizer/tlist.h"
33
34
#include "utils/lsyscache.h"
34
35
35
36
/* local functions */
36
37
static bool join_is_removable (PlannerInfo * root , SpecialJoinInfo * sjinfo );
37
38
static void remove_rel_from_query (PlannerInfo * root , int relid , int ojrelid ,
38
39
Relids joinrelids );
40
+ static void remove_rel_from_restrictinfo (RestrictInfo * rinfo ,
41
+ int relid , int ojrelid );
39
42
static List * remove_rel_from_joinlist (List * joinlist , int relid , int * nremoved );
40
43
static bool rel_supports_distinctness (PlannerInfo * root , RelOptInfo * rel );
41
44
static bool rel_is_distinct_for (PlannerInfo * root , RelOptInfo * rel ,
@@ -470,24 +473,12 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
470
473
{
471
474
/*
472
475
* There might be references to relid or ojrelid in the
473
- * clause_relids as a consequence of PHVs having ph_eval_at sets
476
+ * RestrictInfo, as a consequence of PHVs having ph_eval_at sets
474
477
* that include those. We already checked above that any such PHV
475
478
* is safe, so we can just drop those references.
476
- *
477
- * The clause_relids probably aren't shared with anything else,
478
- * but let's copy them just to be sure.
479
479
*/
480
- rinfo -> clause_relids = bms_copy (rinfo -> clause_relids );
481
- rinfo -> clause_relids = bms_del_member (rinfo -> clause_relids ,
482
- relid );
483
- rinfo -> clause_relids = bms_del_member (rinfo -> clause_relids ,
484
- ojrelid );
485
- /* Likewise for required_relids */
486
- rinfo -> required_relids = bms_copy (rinfo -> required_relids );
487
- rinfo -> required_relids = bms_del_member (rinfo -> required_relids ,
488
- relid );
489
- rinfo -> required_relids = bms_del_member (rinfo -> required_relids ,
490
- ojrelid );
480
+ remove_rel_from_restrictinfo (rinfo , relid , ojrelid );
481
+ /* Now throw it back into the joininfo lists */
491
482
distribute_restrictinfo_to_rels (root , rinfo );
492
483
}
493
484
}
@@ -498,6 +489,62 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
498
489
*/
499
490
}
500
491
492
+ /*
493
+ * Remove any references to relid or ojrelid from the RestrictInfo.
494
+ *
495
+ * We only bother to clean out bits in clause_relids and required_relids,
496
+ * not nullingrel bits in contained Vars and PHVs. (This might have to be
497
+ * improved sometime.) However, if the RestrictInfo contains an OR clause
498
+ * we have to also clean up the sub-clauses.
499
+ */
500
+ static void
501
+ remove_rel_from_restrictinfo (RestrictInfo * rinfo , int relid , int ojrelid )
502
+ {
503
+ /*
504
+ * The clause_relids probably aren't shared with anything else, but let's
505
+ * copy them just to be sure.
506
+ */
507
+ rinfo -> clause_relids = bms_copy (rinfo -> clause_relids );
508
+ rinfo -> clause_relids = bms_del_member (rinfo -> clause_relids , relid );
509
+ rinfo -> clause_relids = bms_del_member (rinfo -> clause_relids , ojrelid );
510
+ /* Likewise for required_relids */
511
+ rinfo -> required_relids = bms_copy (rinfo -> required_relids );
512
+ rinfo -> required_relids = bms_del_member (rinfo -> required_relids , relid );
513
+ rinfo -> required_relids = bms_del_member (rinfo -> required_relids , ojrelid );
514
+
515
+ /* If it's an OR, recurse to clean up sub-clauses */
516
+ if (restriction_is_or_clause (rinfo ))
517
+ {
518
+ ListCell * lc ;
519
+
520
+ Assert (is_orclause (rinfo -> orclause ));
521
+ foreach (lc , ((BoolExpr * ) rinfo -> orclause )-> args )
522
+ {
523
+ Node * orarg = (Node * ) lfirst (lc );
524
+
525
+ /* OR arguments should be ANDs or sub-RestrictInfos */
526
+ if (is_andclause (orarg ))
527
+ {
528
+ List * andargs = ((BoolExpr * ) orarg )-> args ;
529
+ ListCell * lc2 ;
530
+
531
+ foreach (lc2 , andargs )
532
+ {
533
+ RestrictInfo * rinfo2 = lfirst_node (RestrictInfo , lc2 );
534
+
535
+ remove_rel_from_restrictinfo (rinfo2 , relid , ojrelid );
536
+ }
537
+ }
538
+ else
539
+ {
540
+ RestrictInfo * rinfo2 = castNode (RestrictInfo , orarg );
541
+
542
+ remove_rel_from_restrictinfo (rinfo2 , relid , ojrelid );
543
+ }
544
+ }
545
+ }
546
+ }
547
+
501
548
/*
502
549
* Remove any occurrences of the target relid from a joinlist structure.
503
550
*
0 commit comments