summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path')
-rw-r--r--src/backend/optimizer/path/allpaths.c1
-rw-r--r--src/backend/optimizer/path/clausesel.c6
-rw-r--r--src/backend/optimizer/path/costsize.c2
-rw-r--r--src/backend/optimizer/path/equivclass.c168
-rw-r--r--src/backend/optimizer/path/joinrels.c1
-rw-r--r--src/backend/optimizer/path/pathkeys.c40
6 files changed, 52 insertions, 166 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 26b294d5d0..ae0f9bdc8a 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -2745,7 +2745,6 @@ set_function_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
if (var)
pathkeys = build_expression_pathkey(root,
(Expr *) var,
- NULL, /* below outer joins */
Int8LessOperator,
rel->relids,
false);
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 61db6ad951..435438a173 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -716,12 +716,6 @@ clause_selectivity_ext(PlannerInfo *root,
}
/*
- * If the clause is marked redundant, always return 1.0.
- */
- if (rinfo->norm_selec > 1)
- return (Selectivity) 1.0;
-
- /*
* If possible, cache the result of the selectivity calculation for
* the clause. We can cache if varRelid is zero or the clause
* contains only vars of that relid --- otherwise varRelid will affect
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 7d957a47a4..7918bb6f0d 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -4787,7 +4787,6 @@ compute_semi_anti_join_factors(PlannerInfo *root,
norm_sjinfo.commute_below = NULL;
/* we don't bother trying to make the remaining fields valid */
norm_sjinfo.lhs_strict = false;
- norm_sjinfo.delay_upper_joins = false;
norm_sjinfo.semi_can_btree = false;
norm_sjinfo.semi_can_hash = false;
norm_sjinfo.semi_operators = NIL;
@@ -4956,7 +4955,6 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
sjinfo.commute_below = NULL;
/* we don't bother trying to make the remaining fields valid */
sjinfo.lhs_strict = false;
- sjinfo.delay_upper_joins = false;
sjinfo.semi_can_btree = false;
sjinfo.semi_can_hash = false;
sjinfo.semi_operators = NIL;
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 490953f2ff..007229d26c 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -34,7 +34,7 @@
static EquivalenceMember *add_eq_member(EquivalenceClass *ec,
- Expr *expr, Relids relids, Relids nullable_relids,
+ Expr *expr, Relids relids,
EquivalenceMember *parent,
Oid datatype);
static bool is_exprlist_member(Expr *node, List *exprs);
@@ -131,9 +131,7 @@ process_equivalence(PlannerInfo *root,
Expr *item1;
Expr *item2;
Relids item1_relids,
- item2_relids,
- item1_nullable_relids,
- item2_nullable_relids;
+ item2_relids;
List *opfamilies;
EquivalenceClass *ec1,
*ec2;
@@ -202,12 +200,10 @@ process_equivalence(PlannerInfo *root,
make_restrictinfo(root,
(Expr *) ntest,
restrictinfo->is_pushed_down,
- restrictinfo->outerjoin_delayed,
restrictinfo->pseudoconstant,
restrictinfo->security_level,
NULL,
- restrictinfo->outer_relids,
- restrictinfo->nullable_relids);
+ restrictinfo->outer_relids);
}
return false;
}
@@ -225,12 +221,6 @@ process_equivalence(PlannerInfo *root,
return false; /* RHS is non-strict but not constant */
}
- /* Calculate nullable-relid sets for each side of the clause */
- item1_nullable_relids = bms_intersect(item1_relids,
- restrictinfo->nullable_relids);
- item2_nullable_relids = bms_intersect(item2_relids,
- restrictinfo->nullable_relids);
-
/*
* We use the declared input types of the operator, not exprType() of the
* inputs, as the nominal datatypes for opfamily lookup. This presumes
@@ -400,7 +390,7 @@ process_equivalence(PlannerInfo *root,
else if (ec1)
{
/* Case 3: add item2 to ec1 */
- em2 = add_eq_member(ec1, item2, item2_relids, item2_nullable_relids,
+ em2 = add_eq_member(ec1, item2, item2_relids,
NULL, item2_type);
ec1->ec_sources = lappend(ec1->ec_sources, restrictinfo);
ec1->ec_below_outer_join |= below_outer_join;
@@ -418,7 +408,7 @@ process_equivalence(PlannerInfo *root,
else if (ec2)
{
/* Case 3: add item1 to ec2 */
- em1 = add_eq_member(ec2, item1, item1_relids, item1_nullable_relids,
+ em1 = add_eq_member(ec2, item1, item1_relids,
NULL, item1_type);
ec2->ec_sources = lappend(ec2->ec_sources, restrictinfo);
ec2->ec_below_outer_join |= below_outer_join;
@@ -452,9 +442,9 @@ process_equivalence(PlannerInfo *root,
ec->ec_min_security = restrictinfo->security_level;
ec->ec_max_security = restrictinfo->security_level;
ec->ec_merged = NULL;
- em1 = add_eq_member(ec, item1, item1_relids, item1_nullable_relids,
+ em1 = add_eq_member(ec, item1, item1_relids,
NULL, item1_type);
- em2 = add_eq_member(ec, item2, item2_relids, item2_nullable_relids,
+ em2 = add_eq_member(ec, item2, item2_relids,
NULL, item2_type);
root->eq_classes = lappend(root->eq_classes, ec);
@@ -545,13 +535,12 @@ canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation)
*/
static EquivalenceMember *
add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
- Relids nullable_relids, EquivalenceMember *parent, Oid datatype)
+ EquivalenceMember *parent, Oid datatype)
{
EquivalenceMember *em = makeNode(EquivalenceMember);
em->em_expr = expr;
em->em_relids = relids;
- em->em_nullable_relids = nullable_relids;
em->em_is_const = false;
em->em_is_child = (parent != NULL);
em->em_datatype = datatype;
@@ -588,13 +577,6 @@ add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
* equivalence class it is a member of; if none, optionally build a new
* single-member EquivalenceClass for it.
*
- * expr is the expression, and nullable_relids is the set of base relids
- * that are potentially nullable below it. We actually only care about
- * the set of such relids that are used in the expression; but for caller
- * convenience, we perform that intersection step here. The caller need
- * only be sure that nullable_relids doesn't omit any nullable rels that
- * might appear in the expr.
- *
* sortref is the SortGroupRef of the originating SortGroupClause, if any,
* or zero if not. (It should never be zero if the expression is volatile!)
*
@@ -623,7 +605,6 @@ add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
EquivalenceClass *
get_eclass_for_sort_expr(PlannerInfo *root,
Expr *expr,
- Relids nullable_relids,
List *opfamilies,
Oid opcintype,
Oid collation,
@@ -719,13 +700,12 @@ get_eclass_for_sort_expr(PlannerInfo *root,
elog(ERROR, "volatile EquivalenceClass has no sortref");
/*
- * Get the precise set of nullable relids appearing in the expression.
+ * Get the precise set of relids appearing in the expression.
*/
expr_relids = pull_varnos(root, (Node *) expr);
- nullable_relids = bms_intersect(nullable_relids, expr_relids);
newem = add_eq_member(newec, copyObject(expr), expr_relids,
- nullable_relids, NULL, opcintype);
+ NULL, opcintype);
/*
* add_eq_member doesn't check for volatile functions, set-returning
@@ -1163,11 +1143,8 @@ generate_base_implied_equalities_const(PlannerInfo *root,
{
RestrictInfo *restrictinfo = (RestrictInfo *) linitial(ec->ec_sources);
- if (bms_membership(restrictinfo->required_relids) != BMS_MULTIPLE)
- {
- distribute_restrictinfo_to_rels(root, restrictinfo);
- return;
- }
+ distribute_restrictinfo_to_rels(root, restrictinfo);
+ return;
}
/*
@@ -1211,8 +1188,6 @@ generate_base_implied_equalities_const(PlannerInfo *root,
rinfo = process_implied_equality(root, eq_op, ec->ec_collation,
cur_em->em_expr, const_em->em_expr,
bms_copy(ec->ec_relids),
- bms_union(cur_em->em_nullable_relids,
- const_em->em_nullable_relids),
ec->ec_min_security,
ec->ec_below_outer_join,
cur_em->em_is_const);
@@ -1285,8 +1260,6 @@ generate_base_implied_equalities_no_const(PlannerInfo *root,
rinfo = process_implied_equality(root, eq_op, ec->ec_collation,
prev_em->em_expr, cur_em->em_expr,
bms_copy(ec->ec_relids),
- bms_union(prev_em->em_nullable_relids,
- cur_em->em_nullable_relids),
ec->ec_min_security,
ec->ec_below_outer_join,
false);
@@ -1889,8 +1862,6 @@ create_join_clause(PlannerInfo *root,
rightem->em_expr,
bms_union(leftem->em_relids,
rightem->em_relids),
- bms_union(leftem->em_nullable_relids,
- rightem->em_nullable_relids),
ec->ec_min_security);
/* If it's a child clause, copy the parent's rinfo_serial */
@@ -1979,23 +1950,11 @@ create_join_clause(PlannerInfo *root,
* If we don't find any match for a set-aside outer join clause, we must
* throw it back into the regular joinclause processing by passing it to
* distribute_restrictinfo_to_rels(). If we do generate a derived clause,
- * however, the outer-join clause is redundant. We still throw it back,
- * because otherwise the join will be seen as a clauseless join and avoided
- * during join order searching; but we mark it as redundant to keep from
- * messing up the joinrel's size estimate. (This behavior means that the
- * API for this routine is uselessly complex: we could have just put all
- * the clauses into the regular processing initially. We keep it because
- * someday we might want to do something else, such as inserting "dummy"
- * joinclauses instead of real ones.)
- *
- * Outer join clauses that are marked outerjoin_delayed are special: this
- * condition means that one or both VARs might go to null due to a lower
- * outer join. We can still push a constant through the clause, but only
- * if its operator is strict; and we *have to* throw the clause back into
- * regular joinclause processing. By keeping the strict join clause,
- * we ensure that any null-extended rows that are mistakenly generated due
- * to suppressing rows not matching the constant will be rejected at the
- * upper outer join. (This doesn't work for full-join clauses.)
+ * however, the outer-join clause is redundant. We must still put some
+ * clause into the regular processing, because otherwise the join will be
+ * seen as a clauseless join and avoided during join order searching.
+ * We handle this by generating a constant-TRUE clause that is marked with
+ * required_relids that make it a join between the correct relations.
*/
void
reconsider_outer_join_clauses(PlannerInfo *root)
@@ -2021,10 +1980,14 @@ reconsider_outer_join_clauses(PlannerInfo *root)
/* remove it from the list */
root->left_join_clauses =
foreach_delete_current(root->left_join_clauses, cell);
- /* we throw it back anyway (see notes above) */
- /* but the thrown-back clause has no extra selectivity */
- rinfo->norm_selec = 2.0;
- rinfo->outer_selec = 1.0;
+ /* throw back a dummy replacement clause (see notes above) */
+ rinfo = make_restrictinfo(root,
+ (Expr *) makeBoolConst(true, false),
+ true, /* is_pushed_down */
+ false, /* pseudoconstant */
+ 0, /* security_level */
+ rinfo->required_relids,
+ rinfo->outer_relids);
distribute_restrictinfo_to_rels(root, rinfo);
}
}
@@ -2042,10 +2005,14 @@ reconsider_outer_join_clauses(PlannerInfo *root)
/* remove it from the list */
root->right_join_clauses =
foreach_delete_current(root->right_join_clauses, cell);
- /* we throw it back anyway (see notes above) */
- /* but the thrown-back clause has no extra selectivity */
- rinfo->norm_selec = 2.0;
- rinfo->outer_selec = 1.0;
+ /* throw back a dummy replacement clause (see notes above) */
+ rinfo = make_restrictinfo(root,
+ (Expr *) makeBoolConst(true, false),
+ true, /* is_pushed_down */
+ false, /* pseudoconstant */
+ 0, /* security_level */
+ rinfo->required_relids,
+ rinfo->outer_relids);
distribute_restrictinfo_to_rels(root, rinfo);
}
}
@@ -2063,10 +2030,14 @@ reconsider_outer_join_clauses(PlannerInfo *root)
/* remove it from the list */
root->full_join_clauses =
foreach_delete_current(root->full_join_clauses, cell);
- /* we throw it back anyway (see notes above) */
- /* but the thrown-back clause has no extra selectivity */
- rinfo->norm_selec = 2.0;
- rinfo->outer_selec = 1.0;
+ /* throw back a dummy replacement clause (see notes above) */
+ rinfo = make_restrictinfo(root,
+ (Expr *) makeBoolConst(true, false),
+ true, /* is_pushed_down */
+ false, /* pseudoconstant */
+ 0, /* security_level */
+ rinfo->required_relids,
+ rinfo->outer_relids);
distribute_restrictinfo_to_rels(root, rinfo);
}
}
@@ -2110,18 +2081,13 @@ reconsider_outer_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo,
left_type,
right_type,
inner_datatype;
- Relids inner_relids,
- inner_nullable_relids;
+ Relids inner_relids;
ListCell *lc1;
Assert(is_opclause(rinfo->clause));
opno = ((OpExpr *) rinfo->clause)->opno;
collation = ((OpExpr *) rinfo->clause)->inputcollid;
- /* If clause is outerjoin_delayed, operator must be strict */
- if (rinfo->outerjoin_delayed && !op_strict(opno))
- return false;
-
/* Extract needed info from the clause */
op_input_types(opno, &left_type, &right_type);
if (outer_on_left)
@@ -2138,8 +2104,6 @@ reconsider_outer_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo,
inner_datatype = left_type;
inner_relids = rinfo->left_relids;
}
- inner_nullable_relids = bms_intersect(inner_relids,
- rinfo->nullable_relids);
/* Scan EquivalenceClasses for a match to outervar */
foreach(lc1, root->eq_classes)
@@ -2200,7 +2164,6 @@ reconsider_outer_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo,
innervar,
cur_em->em_expr,
bms_copy(inner_relids),
- bms_copy(inner_nullable_relids),
cur_ec->ec_min_security);
if (process_equivalence(root, &newrinfo, true))
match = true;
@@ -2238,15 +2201,9 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
left_type,
right_type;
Relids left_relids,
- right_relids,
- left_nullable_relids,
- right_nullable_relids;
+ right_relids;
ListCell *lc1;
- /* Can't use an outerjoin_delayed clause here */
- if (rinfo->outerjoin_delayed)
- return false;
-
/* Extract needed info from the clause */
Assert(is_opclause(rinfo->clause));
opno = ((OpExpr *) rinfo->clause)->opno;
@@ -2256,10 +2213,6 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
rightvar = (Expr *) get_rightop(rinfo->clause);
left_relids = rinfo->left_relids;
right_relids = rinfo->right_relids;
- left_nullable_relids = bms_intersect(left_relids,
- rinfo->nullable_relids);
- right_nullable_relids = bms_intersect(right_relids,
- rinfo->nullable_relids);
foreach(lc1, root->eq_classes)
{
@@ -2361,7 +2314,6 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
leftvar,
cur_em->em_expr,
bms_copy(left_relids),
- bms_copy(left_nullable_relids),
cur_ec->ec_min_security);
if (process_equivalence(root, &newrinfo, true))
matchleft = true;
@@ -2377,7 +2329,6 @@ reconsider_full_join_clause(PlannerInfo *root, OuterJoinClauseInfo *ojcinfo)
rightvar,
cur_em->em_expr,
bms_copy(right_relids),
- bms_copy(right_nullable_relids),
cur_ec->ec_min_security);
if (process_equivalence(root, &newrinfo, true))
matchright = true;
@@ -2675,7 +2626,6 @@ add_child_rel_equivalences(PlannerInfo *root,
/* OK, generate transformed child version */
Expr *child_expr;
Relids new_relids;
- Relids new_nullable_relids;
if (parent_rel->reloptkind == RELOPT_BASEREL)
{
@@ -2705,21 +2655,7 @@ add_child_rel_equivalences(PlannerInfo *root,
top_parent_relids);
new_relids = bms_add_members(new_relids, child_relids);
- /*
- * And likewise for nullable_relids. Note this code assumes
- * parent and child relids are singletons.
- */
- new_nullable_relids = cur_em->em_nullable_relids;
- if (bms_overlap(new_nullable_relids, top_parent_relids))
- {
- new_nullable_relids = bms_difference(new_nullable_relids,
- top_parent_relids);
- new_nullable_relids = bms_add_members(new_nullable_relids,
- child_relids);
- }
-
- (void) add_eq_member(cur_ec, child_expr,
- new_relids, new_nullable_relids,
+ (void) add_eq_member(cur_ec, child_expr, new_relids,
cur_em, cur_em->em_datatype);
/* Record this EC index for the child rel */
@@ -2816,7 +2752,6 @@ add_child_join_rel_equivalences(PlannerInfo *root,
/* Yes, generate transformed child version */
Expr *child_expr;
Relids new_relids;
- Relids new_nullable_relids;
if (parent_joinrel->reloptkind == RELOPT_JOINREL)
{
@@ -2847,20 +2782,7 @@ add_child_join_rel_equivalences(PlannerInfo *root,
top_parent_relids);
new_relids = bms_add_members(new_relids, child_relids);
- /*
- * For nullable_relids, we must selectively replace parent
- * nullable relids with child ones.
- */
- new_nullable_relids = cur_em->em_nullable_relids;
- if (bms_overlap(new_nullable_relids, top_parent_relids))
- new_nullable_relids =
- adjust_child_relids_multilevel(root,
- new_nullable_relids,
- child_joinrel,
- child_joinrel->top_parent);
-
- (void) add_eq_member(cur_ec, child_expr,
- new_relids, new_nullable_relids,
+ (void) add_eq_member(cur_ec, child_expr, new_relids,
cur_em, cur_em->em_datatype);
}
}
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 56dd1073c5..d7cb11c851 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -743,7 +743,6 @@ make_join_rel(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2)
sjinfo->commute_below = NULL;
/* we don't bother trying to make the remaining fields valid */
sjinfo->lhs_strict = false;
- sjinfo->delay_upper_joins = false;
sjinfo->semi_can_btree = false;
sjinfo->semi_can_hash = false;
sjinfo->semi_operators = NIL;
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index d2e241c983..c4e7f97f68 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -180,9 +180,6 @@ pathkey_is_redundant(PathKey *new_pathkey, List *pathkeys)
* Given an expression and sort-order information, create a PathKey.
* The result is always a "canonical" PathKey, but it might be redundant.
*
- * expr is the expression, and nullable_relids is the set of base relids
- * that are potentially nullable below it.
- *
* If the PathKey is being generated from a SortGroupClause, sortref should be
* the SortGroupClause's SortGroupRef; otherwise zero.
*
@@ -198,7 +195,6 @@ pathkey_is_redundant(PathKey *new_pathkey, List *pathkeys)
static PathKey *
make_pathkey_from_sortinfo(PlannerInfo *root,
Expr *expr,
- Relids nullable_relids,
Oid opfamily,
Oid opcintype,
Oid collation,
@@ -234,7 +230,7 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
equality_op);
/* Now find or (optionally) create a matching EquivalenceClass */
- eclass = get_eclass_for_sort_expr(root, expr, nullable_relids,
+ eclass = get_eclass_for_sort_expr(root, expr,
opfamilies, opcintype, collation,
sortref, rel, create_it);
@@ -257,7 +253,6 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
static PathKey *
make_pathkey_from_sortop(PlannerInfo *root,
Expr *expr,
- Relids nullable_relids,
Oid ordering_op,
bool nulls_first,
Index sortref,
@@ -279,7 +274,6 @@ make_pathkey_from_sortop(PlannerInfo *root,
return make_pathkey_from_sortinfo(root,
expr,
- nullable_relids,
opfamily,
opcintype,
collation,
@@ -584,12 +578,10 @@ build_index_pathkeys(PlannerInfo *root,
}
/*
- * OK, try to make a canonical pathkey for this sort key. Note we're
- * underneath any outer joins, so nullable_relids should be NULL.
+ * OK, try to make a canonical pathkey for this sort key.
*/
cpathkey = make_pathkey_from_sortinfo(root,
indexkey,
- NULL,
index->sortopfamily[i],
index->opcintype[i],
index->indexcollations[i],
@@ -743,14 +735,12 @@ build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel,
/*
* Try to make a canonical pathkey for this partkey.
*
- * We're considering a baserel scan, so nullable_relids should be
- * NULL. Also, we assume the PartitionDesc lists any NULL partition
- * last, so we treat the scan like a NULLS LAST index: we have
- * nulls_first for backwards scan only.
+ * We assume the PartitionDesc lists any NULL partition last, so we
+ * treat the scan like a NULLS LAST index: we have nulls_first for
+ * backwards scan only.
*/
cpathkey = make_pathkey_from_sortinfo(root,
keyCol,
- NULL,
partscheme->partopfamily[i],
partscheme->partopcintype[i],
partscheme->partcollation[i],
@@ -799,7 +789,7 @@ build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel,
* Build a pathkeys list that describes an ordering by a single expression
* using the given sort operator.
*
- * expr, nullable_relids, and rel are as for make_pathkey_from_sortinfo.
+ * expr and rel are as for make_pathkey_from_sortinfo.
* We induce the other arguments assuming default sort order for the operator.
*
* Similarly to make_pathkey_from_sortinfo, the result is NIL if create_it
@@ -808,7 +798,6 @@ build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel,
List *
build_expression_pathkey(PlannerInfo *root,
Expr *expr,
- Relids nullable_relids,
Oid opno,
Relids rel,
bool create_it)
@@ -827,7 +816,6 @@ build_expression_pathkey(PlannerInfo *root,
cpathkey = make_pathkey_from_sortinfo(root,
expr,
- nullable_relids,
opfamily,
opcintype,
exprCollation((Node *) expr),
@@ -908,14 +896,11 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
* expression is *not* volatile in the outer query: it's just
* a Var referencing whatever the subquery emitted. (IOW, the
* outer query isn't going to re-execute the volatile
- * expression itself.) So this is okay. Likewise, it's
- * correct to pass nullable_relids = NULL, because we're
- * underneath any outer joins appearing in the outer query.
+ * expression itself.) So this is okay.
*/
outer_ec =
get_eclass_for_sort_expr(root,
(Expr *) outer_var,
- NULL,
sub_eclass->ec_opfamilies,
sub_member->em_datatype,
sub_eclass->ec_collation,
@@ -997,7 +982,6 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
/* See if we have a matching EC for the TLE */
outer_ec = get_eclass_for_sort_expr(root,
(Expr *) outer_var,
- NULL,
sub_eclass->ec_opfamilies,
sub_expr_type,
sub_expr_coll,
@@ -1138,13 +1122,6 @@ build_join_pathkeys(PlannerInfo *root,
* The resulting PathKeys are always in canonical form. (Actually, there
* is no longer any code anywhere that creates non-canonical PathKeys.)
*
- * We assume that root->nullable_baserels is the set of base relids that could
- * have gone to NULL below the SortGroupClause expressions. This is okay if
- * the expressions came from the query's top level (ORDER BY, DISTINCT, etc)
- * and if this function is only invoked after deconstruct_jointree. In the
- * future we might have to make callers pass in the appropriate
- * nullable-relids set, but for now it seems unnecessary.
- *
* 'sortclauses' is a list of SortGroupClause nodes
* 'tlist' is the targetlist to find the referenced tlist entries in
*/
@@ -1210,7 +1187,6 @@ make_pathkeys_for_sortclauses_extended(PlannerInfo *root,
}
pathkey = make_pathkey_from_sortop(root,
sortkey,
- root->nullable_baserels,
sortcl->sortop,
sortcl->nulls_first,
sortcl->tleSortGroupRef,
@@ -1268,7 +1244,6 @@ initialize_mergeclause_eclasses(PlannerInfo *root, RestrictInfo *restrictinfo)
restrictinfo->left_ec =
get_eclass_for_sort_expr(root,
(Expr *) get_leftop(clause),
- restrictinfo->nullable_relids,
restrictinfo->mergeopfamilies,
lefttype,
((OpExpr *) clause)->inputcollid,
@@ -1278,7 +1253,6 @@ initialize_mergeclause_eclasses(PlannerInfo *root, RestrictInfo *restrictinfo)
restrictinfo->right_ec =
get_eclass_for_sort_expr(root,
(Expr *) get_rightop(clause),
- restrictinfo->nullable_relids,
restrictinfo->mergeopfamilies,
righttype,
((OpExpr *) clause)->inputcollid,