summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/clauses.c65
-rw-r--r--src/backend/optimizer/util/pathnode.c17
-rw-r--r--src/backend/optimizer/util/restrictinfo.c64
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.