diff options
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 65 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 17 | ||||
-rw-r--r-- | src/backend/optimizer/util/restrictinfo.c | 64 |
3 files changed, 66 insertions, 80 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 663fa7cd339..d7ff17c363d 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2157,71 +2157,6 @@ CommuteOpExpr(OpExpr *clause) } /* - * CommuteRowCompareExpr: commute a RowCompareExpr clause - * - * XXX the clause is destructively modified! - */ -void -CommuteRowCompareExpr(RowCompareExpr *clause) -{ - List *newops; - List *temp; - ListCell *l; - - /* Sanity checks: caller is at fault if these fail */ - if (!IsA(clause, RowCompareExpr)) - elog(ERROR, "expected a RowCompareExpr"); - - /* Build list of commuted operators */ - newops = NIL; - foreach(l, clause->opnos) - { - Oid opoid = lfirst_oid(l); - - opoid = get_commutator(opoid); - if (!OidIsValid(opoid)) - elog(ERROR, "could not find commutator for operator %u", - lfirst_oid(l)); - newops = lappend_oid(newops, opoid); - } - - /* - * modify the clause in-place! - */ - switch (clause->rctype) - { - case ROWCOMPARE_LT: - clause->rctype = ROWCOMPARE_GT; - break; - case ROWCOMPARE_LE: - clause->rctype = ROWCOMPARE_GE; - break; - case ROWCOMPARE_GE: - clause->rctype = ROWCOMPARE_LE; - break; - case ROWCOMPARE_GT: - clause->rctype = ROWCOMPARE_LT; - break; - default: - elog(ERROR, "unexpected RowCompare type: %d", - (int) clause->rctype); - break; - } - - clause->opnos = newops; - - /* - * Note: we need not change the opfamilies list; we assume any btree - * opfamily containing an operator will also contain its commutator. - * Collations don't change either. - */ - - temp = clause->largs; - clause->largs = clause->rargs; - clause->rargs = temp; -} - -/* * Helper for eval_const_expressions: check that datatype of an attribute * is still what it was when the expression was parsed. This is needed to * guard against improper simplification after ALTER COLUMN TYPE. (XXX we diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 08133a28fd2..a3e64110d36 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -1001,10 +1001,8 @@ create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer * Creates a path node for an index scan. * * 'index' is a usable index. - * 'indexclauses' is a list of RestrictInfo nodes representing clauses - * to be used as index qual conditions in the scan. - * 'indexclausecols' is an integer list of index column numbers (zero based) - * the indexclauses can be used with. + * 'indexclauses' is a list of IndexClause nodes representing clauses + * to be enforced as qual conditions in the scan. * 'indexorderbys' is a list of bare expressions (no RestrictInfos) * to be used as index ordering operators in the scan. * 'indexorderbycols' is an integer list of index column numbers (zero based) @@ -1025,7 +1023,6 @@ IndexPath * create_index_path(PlannerInfo *root, IndexOptInfo *index, List *indexclauses, - List *indexclausecols, List *indexorderbys, List *indexorderbycols, List *pathkeys, @@ -1037,8 +1034,6 @@ create_index_path(PlannerInfo *root, { IndexPath *pathnode = makeNode(IndexPath); RelOptInfo *rel = index->rel; - List *indexquals, - *indexqualcols; pathnode->path.pathtype = indexonly ? T_IndexOnlyScan : T_IndexScan; pathnode->path.parent = rel; @@ -1050,15 +1045,8 @@ create_index_path(PlannerInfo *root, pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = pathkeys; - /* Convert clauses to indexquals the executor can handle */ - expand_indexqual_conditions(index, indexclauses, indexclausecols, - &indexquals, &indexqualcols); - - /* Fill in the pathnode */ pathnode->indexinfo = index; pathnode->indexclauses = indexclauses; - pathnode->indexquals = indexquals; - pathnode->indexqualcols = indexqualcols; pathnode->indexorderbys = indexorderbys; pathnode->indexorderbycols = indexorderbycols; pathnode->indexscandir = indexscandir; @@ -3809,7 +3797,6 @@ do { \ FLAT_COPY_PATH(ipath, path, IndexPath); ADJUST_CHILD_ATTRS(ipath->indexclauses); - ADJUST_CHILD_ATTRS(ipath->indexquals); new_path = (Path *) ipath; } break; diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index 1c47c708028..03e5f12d0da 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -289,6 +289,70 @@ make_sub_restrictinfos(Expr *clause, } /* + * commute_restrictinfo + * + * Given a RestrictInfo containing a binary opclause, produce a RestrictInfo + * representing the commutation of that clause. The caller must pass the + * OID of the commutator operator (which it's presumably looked up, else + * it would not know this is valid). + * + * Beware that the result shares sub-structure with the given RestrictInfo. + * That's okay for the intended usage with derived index quals, but might + * be hazardous if the source is subject to change. Also notice that we + * assume without checking that the commutator op is a member of the same + * btree and hash opclasses as the original op. + */ +RestrictInfo * +commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) +{ + RestrictInfo *result; + OpExpr *newclause; + OpExpr *clause = castNode(OpExpr, rinfo->clause); + + Assert(list_length(clause->args) == 2); + + /* flat-copy all the fields of clause ... */ + newclause = makeNode(OpExpr); + memcpy(newclause, clause, sizeof(OpExpr)); + + /* ... and adjust those we need to change to commute it */ + newclause->opno = comm_op; + newclause->opfuncid = InvalidOid; + newclause->args = list_make2(lsecond(clause->args), + linitial(clause->args)); + + /* likewise, flat-copy all the fields of rinfo ... */ + result = makeNode(RestrictInfo); + memcpy(result, rinfo, sizeof(RestrictInfo)); + + /* + * ... and adjust those we need to change. Note in particular that we can + * preserve any cached selectivity or cost estimates, since those ought to + * be the same for the new clause. Likewise we can keep the source's + * parent_ec. + */ + result->clause = (Expr *) newclause; + result->left_relids = rinfo->right_relids; + result->right_relids = rinfo->left_relids; + Assert(result->orclause == NULL); + result->left_ec = rinfo->right_ec; + result->right_ec = rinfo->left_ec; + result->left_em = rinfo->right_em; + result->right_em = rinfo->left_em; + result->scansel_cache = NIL; /* not worth updating this */ + if (rinfo->hashjoinoperator == clause->opno) + result->hashjoinoperator = comm_op; + else + result->hashjoinoperator = InvalidOid; + result->left_bucketsize = rinfo->right_bucketsize; + result->right_bucketsize = rinfo->left_bucketsize; + result->left_mcvfreq = rinfo->right_mcvfreq; + result->right_mcvfreq = rinfo->left_mcvfreq; + + return result; +} + +/* * restriction_is_or_clause * * Returns t iff the restrictinfo node contains an 'or' clause. |