diff --git a/src/backend/optimizer/path/uniquekeys.c b/src/backend/optimizer/path/uniquekeys.c index 91be8a7f6ec..19c894bbea7 100644 --- a/src/backend/optimizer/path/uniquekeys.c +++ b/src/backend/optimizer/path/uniquekeys.c @@ -179,9 +179,17 @@ populate_plain_rel_uniquekeys(PlannerInfo *root, RelOptInfo *rel) nonnullable_valid = true; } + /* + * NULLs in this column do not disambiguate the output rows, + * so the output rows will only be truly distinct if the rows + * containing NULL in this column will be filtered out + * altogether. + */ if (!IsA(colexpr, Var) || - (!var_is_nonnullable(root, (Var *) colexpr, NOTNULL_SOURCE_RELOPT) && - !var_in_nonnullable_vars((Var *) colexpr, nonnullable_vars))) + (!var_is_nonnullable(root, castNode(Var, colexpr), + NOTNULL_SOURCE_RELOPT) && + !var_in_nonnullable_vars(castNode(Var, colexpr), + nonnullable_vars))) nullable = true; } } @@ -246,7 +254,7 @@ populate_subquery_rel_uniquekeys(PlannerInfo *root, RelOptInfo *rel) continue; Assert(lg != NULL); - sgc = (SortGroupClause *) lfirst(lg); + sgc = lfirst_node(SortGroupClause, lg); lg = lnext(topop->groupClauses, lg); if (!add_subquery_key_col(root, rel, sgc, tle, &key_ecs)) @@ -484,9 +492,9 @@ populate_joinrel_uniquekeys(PlannerInfo *root, RelOptInfo *joinrel, /* * Preservation of the LHS keys: unconditional for a semi/antijoin, else - * the RHS must be unique for the clauses so each LHS row yields one join - * row. A lateral reference into the RHS re-executes the LHS per RHS row, - * voiding this. + * the RHS must be unique for the clauses so each LHS row yields at most + * one join row. A lateral reference into the RHS re-executes the LHS per + * RHS row, voiding this. */ if (lhs->uniquekeys != NIL && !bms_overlap(lhs->lateral_relids, rhs->relids) && @@ -853,7 +861,7 @@ uniquekeys_grouping_is_noop(PlannerInfo *root, RelOptInfo *input_rel) if (foreach_current_index(lc) >= root->num_groupby_pathkeys) break; - pos = base_ec_position(root, ((PathKey *) lfirst(lc))->pk_eclass); + pos = base_ec_position(root, castNode(PathKey, lfirst(lc))->pk_eclass); if (pos >= 0) covered = bms_add_member(covered, pos); } @@ -1018,7 +1026,7 @@ get_interesting_unique_ecs(PlannerInfo *root) break; result = add_base_ec_positions(root, result, - ((PathKey *) lfirst(lc))->pk_eclass); + castNode(PathKey, lc)->pk_eclass); } } @@ -1138,7 +1146,7 @@ collect_clause_ecs(PlannerInfo *root, List *clause, Bitmapset **ecs_p) } if (pos < 0) return false; - ec = (EquivalenceClass *) list_nth(root->eq_classes, pos); + ec = list_nth_node(EquivalenceClass, root->eq_classes, pos); if (!ec->ec_has_const) ecs = bms_add_member(ecs, pos); @@ -1191,12 +1199,8 @@ add_uniquekey(RelOptInfo *rel, Bitmapset *eclass_indexes, bool nullable) static bool rel_has_uniquekey_within(RelOptInfo *rel, Bitmapset *ecs, bool null_aware) { - ListCell *lc; - - foreach(lc, rel->uniquekeys) + foreach_node(UniqueKey, ukey, rel->uniquekeys) { - UniqueKey *ukey = lfirst_node(UniqueKey, lc); - if ((!null_aware || !ukey->nullable) && bms_is_subset(ukey->eclass_indexes, ecs)) return true;