Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions

restrictinfo.h File Reference

#include "nodes/relation.h"
Include dependency graph for restrictinfo.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define make_simple_restrictinfo(clause)   make_restrictinfo(clause, true, false, false, NULL, NULL, NULL)

Functions

RestrictInfomake_restrictinfo (Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, Relids required_relids, Relids outer_relids, Relids nullable_relids)
Listmake_restrictinfo_from_bitmapqual (Path *bitmapqual, bool is_pushed_down, bool include_predicates)
Listmake_restrictinfos_from_actual_clauses (PlannerInfo *root, List *clause_list)
bool restriction_is_or_clause (RestrictInfo *restrictinfo)
Listget_actual_clauses (List *restrictinfo_list)
Listget_all_actual_clauses (List *restrictinfo_list)
Listextract_actual_clauses (List *restrictinfo_list, bool pseudoconstant)
void extract_actual_join_clauses (List *restrictinfo_list, List **joinquals, List **otherquals)
bool join_clause_is_movable_to (RestrictInfo *rinfo, Index baserelid)
bool join_clause_is_movable_into (RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer)

Define Documentation

#define make_simple_restrictinfo (   clause  )     make_restrictinfo(clause, true, false, false, NULL, NULL, NULL)

Function Documentation

List* extract_actual_clauses ( List restrictinfo_list,
bool  pseudoconstant 
)
void extract_actual_join_clauses ( List restrictinfo_list,
List **  joinquals,
List **  otherquals 
)

Definition at line 607 of file restrictinfo.c.

References Assert, RestrictInfo::clause, RestrictInfo::is_pushed_down, IsA, lappend(), lfirst, and RestrictInfo::pseudoconstant.

Referenced by create_hashjoin_plan(), create_mergejoin_plan(), and create_nestloop_plan().

{
    ListCell   *l;

    *joinquals = NIL;
    *otherquals = NIL;

    foreach(l, restrictinfo_list)
    {
        RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);

        Assert(IsA(rinfo, RestrictInfo));

        if (rinfo->is_pushed_down)
        {
            if (!rinfo->pseudoconstant)
                *otherquals = lappend(*otherquals, rinfo->clause);
        }
        else
        {
            /* joinquals shouldn't have been marked pseudoconstant */
            Assert(!rinfo->pseudoconstant);
            *joinquals = lappend(*joinquals, rinfo->clause);
        }
    }
}

List* get_actual_clauses ( List restrictinfo_list  ) 

Definition at line 528 of file restrictinfo.c.

References Assert, RestrictInfo::clause, IsA, lappend(), lfirst, and RestrictInfo::pseudoconstant.

Referenced by create_bitmap_subplan(), create_hashjoin_plan(), create_indexscan_plan(), create_join_plan(), create_mergejoin_plan(), find_indexpath_quals(), and make_restrictinfo_from_bitmapqual().

{
    List       *result = NIL;
    ListCell   *l;

    foreach(l, restrictinfo_list)
    {
        RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);

        Assert(IsA(rinfo, RestrictInfo));

        Assert(!rinfo->pseudoconstant);

        result = lappend(result, rinfo->clause);
    }
    return result;
}

List* get_all_actual_clauses ( List restrictinfo_list  ) 

Definition at line 555 of file restrictinfo.c.

References Assert, RestrictInfo::clause, IsA, lappend(), and lfirst.

Referenced by set_append_rel_size().

{
    List       *result = NIL;
    ListCell   *l;

    foreach(l, restrictinfo_list)
    {
        RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);

        Assert(IsA(rinfo, RestrictInfo));

        result = lappend(result, rinfo->clause);
    }
    return result;
}

bool join_clause_is_movable_into ( RestrictInfo rinfo,
Relids  currentrelids,
Relids  current_and_outer 
)

Definition at line 703 of file restrictinfo.c.

References bms_is_subset(), bms_overlap(), RestrictInfo::clause_relids, RestrictInfo::nullable_relids, and RestrictInfo::outer_relids.

Referenced by create_nestloop_path(), get_baserel_parampathinfo(), get_joinrel_parampathinfo(), and has_indexed_join_quals().

{
    /* Clause must be evaluatable given available context */
    if (!bms_is_subset(rinfo->clause_relids, current_and_outer))
        return false;

    /* Clause must physically reference target rel(s) */
    if (!bms_overlap(currentrelids, rinfo->clause_relids))
        return false;

    /* Cannot move an outer-join clause into the join's outer side */
    if (bms_overlap(currentrelids, rinfo->outer_relids))
        return false;

    /* Target rel(s) must not be nullable below the clause */
    if (bms_overlap(currentrelids, rinfo->nullable_relids))
        return false;

    return true;
}

bool join_clause_is_movable_to ( RestrictInfo rinfo,
Index  baserelid 
)

Definition at line 660 of file restrictinfo.c.

References bms_is_member(), RestrictInfo::clause_relids, RestrictInfo::nullable_relids, and RestrictInfo::outer_relids.

Referenced by check_partial_indexes(), create_or_index_quals(), match_join_clauses_to_index(), and postgresGetForeignPaths().

{
    /* Clause must physically reference target rel */
    if (!bms_is_member(baserelid, rinfo->clause_relids))
        return false;

    /* Cannot move an outer-join clause into the join's outer side */
    if (bms_is_member(baserelid, rinfo->outer_relids))
        return false;

    /* Target rel must not be nullable below the clause */
    if (bms_is_member(baserelid, rinfo->nullable_relids))
        return false;

    return true;
}

RestrictInfo* make_restrictinfo ( Expr clause,
bool  is_pushed_down,
bool  outerjoin_delayed,
bool  pseudoconstant,
Relids  required_relids,
Relids  outer_relids,
Relids  nullable_relids 
)

Definition at line 56 of file restrictinfo.c.

References and_clause(), Assert, make_restrictinfo_internal(), make_sub_restrictinfos(), NULL, and or_clause().

Referenced by build_implied_join_equality(), distribute_qual_to_rels(), make_restrictinfo_from_bitmapqual(), and make_restrictinfos_from_actual_clauses().

{
    /*
     * If it's an OR clause, build a modified copy with RestrictInfos inserted
     * above each subclause of the top-level AND/OR structure.
     */
    if (or_clause((Node *) clause))
        return (RestrictInfo *) make_sub_restrictinfos(clause,
                                                       is_pushed_down,
                                                       outerjoin_delayed,
                                                       pseudoconstant,
                                                       required_relids,
                                                       outer_relids,
                                                       nullable_relids);

    /* Shouldn't be an AND clause, else AND/OR flattening messed up */
    Assert(!and_clause((Node *) clause));

    return make_restrictinfo_internal(clause,
                                      NULL,
                                      is_pushed_down,
                                      outerjoin_delayed,
                                      pseudoconstant,
                                      required_relids,
                                      outer_relids,
                                      nullable_relids);
}

List* make_restrictinfo_from_bitmapqual ( Path bitmapqual,
bool  is_pushed_down,
bool  include_predicates 
)

Definition at line 117 of file restrictinfo.c.

References Assert, BitmapOrPath::bitmapquals, BitmapAndPath::bitmapquals, RestrictInfo::clause, elog, ERROR, get_actual_clauses(), IndexPath::indexclauses, IndexPath::indexinfo, IndexOptInfo::indpred, IsA, lappend(), lfirst, linitial, list_concat(), list_concat_unique(), list_copy(), list_length(), list_make1, make_andclause(), make_orclause(), make_restrictinfo(), make_restrictinfo_from_bitmapqual(), make_restrictinfo_internal(), NIL, nodeTag, NULL, or_clause(), RestrictInfo::orclause, predicate_implied_by(), and restriction_is_or_clause().

Referenced by create_or_index_quals(), and make_restrictinfo_from_bitmapqual().

{
    List       *result;
    ListCell   *l;

    if (IsA(bitmapqual, BitmapAndPath))
    {
        BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;

        /*
         * There may well be redundant quals among the subplans, since a
         * top-level WHERE qual might have gotten used to form several
         * different index quals.  We don't try exceedingly hard to eliminate
         * redundancies, but we do eliminate obvious duplicates by using
         * list_concat_unique.
         */
        result = NIL;
        foreach(l, apath->bitmapquals)
        {
            List       *sublist;

            sublist = make_restrictinfo_from_bitmapqual((Path *) lfirst(l),
                                                        is_pushed_down,
                                                        include_predicates);
            result = list_concat_unique(result, sublist);
        }
    }
    else if (IsA(bitmapqual, BitmapOrPath))
    {
        BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
        List       *withris = NIL;
        List       *withoutris = NIL;

        /*
         * Here, we only detect qual-free subplans.  A qual-free subplan would
         * cause us to generate "... OR true ..."  which we may as well reduce
         * to just "true".  We do not try to eliminate redundant subclauses
         * because (a) it's not as likely as in the AND case, and (b) we might
         * well be working with hundreds or even thousands of OR conditions,
         * perhaps from a long IN list.  The performance of list_append_unique
         * would be unacceptable.
         */
        foreach(l, opath->bitmapquals)
        {
            List       *sublist;

            sublist = make_restrictinfo_from_bitmapqual((Path *) lfirst(l),
                                                        is_pushed_down,
                                                        include_predicates);
            if (sublist == NIL)
            {
                /*
                 * If we find a qual-less subscan, it represents a constant
                 * TRUE, and hence the OR result is also constant TRUE, so we
                 * can stop here.
                 */
                return NIL;
            }

            /*
             * If the sublist contains multiple RestrictInfos, we create an
             * AND subclause.  If there's just one, we have to check if it's
             * an OR clause, and if so flatten it to preserve AND/OR flatness
             * of our output.
             *
             * We construct lists with and without sub-RestrictInfos, so as
             * not to have to regenerate duplicate RestrictInfos below.
             */
            if (list_length(sublist) > 1)
            {
                withris = lappend(withris, make_andclause(sublist));
                sublist = get_actual_clauses(sublist);
                withoutris = lappend(withoutris, make_andclause(sublist));
            }
            else
            {
                RestrictInfo *subri = (RestrictInfo *) linitial(sublist);

                Assert(IsA(subri, RestrictInfo));
                if (restriction_is_or_clause(subri))
                {
                    BoolExpr   *subor = (BoolExpr *) subri->orclause;

                    Assert(or_clause((Node *) subor));
                    withris = list_concat(withris,
                                          list_copy(subor->args));
                    subor = (BoolExpr *) subri->clause;
                    Assert(or_clause((Node *) subor));
                    withoutris = list_concat(withoutris,
                                             list_copy(subor->args));
                }
                else
                {
                    withris = lappend(withris, subri);
                    withoutris = lappend(withoutris, subri->clause);
                }
            }
        }

        /*
         * Avoid generating one-element ORs, which could happen due to
         * redundancy elimination or ScalarArrayOpExpr quals.
         */
        if (list_length(withris) <= 1)
            result = withris;
        else
        {
            /* Here's the magic part not available to outside callers */
            result =
                list_make1(make_restrictinfo_internal(make_orclause(withoutris),
                                                      make_orclause(withris),
                                                      is_pushed_down,
                                                      false,
                                                      false,
                                                      NULL,
                                                      NULL,
                                                      NULL));
        }
    }
    else if (IsA(bitmapqual, IndexPath))
    {
        IndexPath  *ipath = (IndexPath *) bitmapqual;

        result = list_copy(ipath->indexclauses);
        if (include_predicates && ipath->indexinfo->indpred != NIL)
        {
            foreach(l, ipath->indexinfo->indpred)
            {
                Expr       *pred = (Expr *) lfirst(l);

                /*
                 * We know that the index predicate must have been implied by
                 * the query condition as a whole, but it may or may not be
                 * implied by the conditions that got pushed into the
                 * bitmapqual.  Avoid generating redundant conditions.
                 */
                if (!predicate_implied_by(list_make1(pred), result))
                    result = lappend(result,
                                     make_restrictinfo(pred,
                                                       is_pushed_down,
                                                       false,
                                                       false,
                                                       NULL,
                                                       NULL,
                                                       NULL));
            }
        }
    }
    else
    {
        elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
        result = NIL;           /* keep compiler quiet */
    }

    return result;
}

List* make_restrictinfos_from_actual_clauses ( PlannerInfo root,
List clause_list 
)

Definition at line 290 of file restrictinfo.c.

References contain_vars_of_level(), contain_volatile_functions(), PlannerInfo::hasPseudoConstantQuals, lappend(), lfirst, make_restrictinfo(), and NULL.

Referenced by set_append_rel_size().

{
    List       *result = NIL;
    ListCell   *l;

    foreach(l, clause_list)
    {
        Expr       *clause = (Expr *) lfirst(l);
        bool        pseudoconstant;
        RestrictInfo *rinfo;

        /*
         * It's pseudoconstant if it contains no Vars and no volatile
         * functions.  We probably can't see any sublinks here, so
         * contain_var_clause() would likely be enough, but for safety use
         * contain_vars_of_level() instead.
         */
        pseudoconstant =
            !contain_vars_of_level((Node *) clause, 0) &&
            !contain_volatile_functions((Node *) clause);
        if (pseudoconstant)
        {
            /* tell createplan.c to check for gating quals */
            root->hasPseudoConstantQuals = true;
        }

        rinfo = make_restrictinfo(clause,
                                  true,
                                  false,
                                  pseudoconstant,
                                  NULL,
                                  NULL,
                                  NULL);
        result = lappend(result, rinfo);
    }
    return result;
}

bool restriction_is_or_clause ( RestrictInfo restrictinfo  ) 

Definition at line 511 of file restrictinfo.c.

References NULL, and RestrictInfo::orclause.

Referenced by create_or_index_quals(), drop_indexable_join_clauses(), generate_bitmap_or_paths(), make_restrictinfo_from_bitmapqual(), and match_join_clauses_to_index().

{
    if (restrictinfo->orclause != NULL)
        return true;
    else
        return false;
}