aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/costsize.c9
-rw-r--r--src/backend/optimizer/path/indxpath.c324
-rw-r--r--src/backend/optimizer/path/joinpath.c67
-rw-r--r--src/backend/optimizer/plan/createplan.c60
-rw-r--r--src/backend/optimizer/plan/initsplan.c24
-rw-r--r--src/backend/optimizer/plan/planagg.c18
-rw-r--r--src/backend/optimizer/plan/subselect.c6
-rw-r--r--src/backend/optimizer/util/clauses.c10
-rw-r--r--src/backend/optimizer/util/pathnode.c10
-rw-r--r--src/backend/optimizer/util/plancat.c8
-rw-r--r--src/backend/optimizer/util/predtest.c83
-rw-r--r--src/backend/optimizer/util/restrictinfo.c3
12 files changed, 364 insertions, 258 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 71685643efa..fbcf7d2b5f5 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -54,7 +54,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.170 2006/12/15 18:42:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.171 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1258,6 +1258,8 @@ cost_mergejoin(MergePath *path, PlannerInfo *root)
Path *outer_path = path->jpath.outerjoinpath;
Path *inner_path = path->jpath.innerjoinpath;
List *mergeclauses = path->path_mergeclauses;
+ List *mergefamilies = path->path_mergefamilies;
+ List *mergestrategies = path->path_mergestrategies;
List *outersortkeys = path->outersortkeys;
List *innersortkeys = path->innersortkeys;
Cost startup_cost = 0;
@@ -1347,13 +1349,16 @@ cost_mergejoin(MergePath *path, PlannerInfo *root)
*
* Since this calculation is somewhat expensive, and will be the same for
* all mergejoin paths associated with the merge clause, we cache the
- * results in the RestrictInfo node.
+ * results in the RestrictInfo node. XXX that won't work anymore once
+ * we support multiple possible orderings!
*/
if (mergeclauses && path->jpath.jointype != JOIN_FULL)
{
firstclause = (RestrictInfo *) linitial(mergeclauses);
if (firstclause->left_mergescansel < 0) /* not computed yet? */
mergejoinscansel(root, (Node *) firstclause->clause,
+ linitial_oid(mergefamilies),
+ linitial_int(mergestrategies),
&firstclause->left_mergescansel,
&firstclause->right_mergescansel);
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index b15affa54d5..af081b82c8e 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.212 2006/10/04 00:29:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.213 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,8 +19,8 @@
#include "access/skey.h"
#include "catalog/pg_am.h"
-#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
+#include "catalog/pg_opfamily.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
@@ -40,10 +40,10 @@
/*
* DoneMatchingIndexKeys() - MACRO
*/
-#define DoneMatchingIndexKeys(classes) (classes[0] == InvalidOid)
+#define DoneMatchingIndexKeys(families) (families[0] == InvalidOid)
-#define IsBooleanOpclass(opclass) \
- ((opclass) == BOOL_BTREE_OPS_OID || (opclass) == BOOL_HASH_OPS_OID)
+#define IsBooleanOpfamily(opfamily) \
+ ((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID)
static List *find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
@@ -61,15 +61,15 @@ static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel,
static List *pull_indexpath_quals(Path *bitmapqual);
static bool lists_intersect_ptr(List *list1, List *list2);
static bool match_clause_to_indexcol(IndexOptInfo *index,
- int indexcol, Oid opclass,
+ int indexcol, Oid opfamily,
RestrictInfo *rinfo,
Relids outer_relids,
SaOpControl saop_control);
-static bool is_indexable_operator(Oid expr_op, Oid opclass,
+static bool is_indexable_operator(Oid expr_op, Oid opfamily,
bool indexkey_on_left);
static bool match_rowcompare_to_indexcol(IndexOptInfo *index,
int indexcol,
- Oid opclass,
+ Oid opfamily,
RowCompareExpr *clause,
Relids outer_relids);
static Relids indexable_outerrelids(RelOptInfo *rel);
@@ -89,17 +89,17 @@ static bool match_index_to_query_keys(PlannerInfo *root,
List *ignorables);
static bool match_boolean_index_clause(Node *clause, int indexcol,
IndexOptInfo *index);
-static bool match_special_index_operator(Expr *clause, Oid opclass,
+static bool match_special_index_operator(Expr *clause, Oid opfamily,
bool indexkey_on_left);
static Expr *expand_boolean_index_clause(Node *clause, int indexcol,
IndexOptInfo *index);
-static List *expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass);
+static List *expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily);
static RestrictInfo *expand_indexqual_rowcompare(RestrictInfo *rinfo,
IndexOptInfo *index,
int indexcol);
-static List *prefix_quals(Node *leftop, Oid opclass,
+static List *prefix_quals(Node *leftop, Oid opfamily,
Const *prefix, Pattern_Prefix_Status pstatus);
-static List *network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass,
+static List *network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily,
Datum rightop);
static Datum string_to_datum(const char *str, Oid datatype);
static Const *string_to_const(const char *str, Oid datatype);
@@ -858,7 +858,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
List *clausegroup_list = NIL;
bool found_outer_clause = false;
int indexcol = 0;
- Oid *classes = index->classlist;
+ Oid *families = index->opfamily;
*found_clause = false; /* default result */
@@ -867,7 +867,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
do
{
- Oid curClass = classes[0];
+ Oid curFamily = families[0];
List *clausegroup = NIL;
ListCell *l;
@@ -879,7 +879,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
Assert(IsA(rinfo, RestrictInfo));
if (match_clause_to_indexcol(index,
indexcol,
- curClass,
+ curFamily,
rinfo,
outer_relids,
saop_control))
@@ -899,7 +899,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
Assert(IsA(rinfo, RestrictInfo));
if (match_clause_to_indexcol(index,
indexcol,
- curClass,
+ curFamily,
rinfo,
outer_relids,
saop_control))
@@ -918,9 +918,9 @@ group_clauses_by_indexkey(IndexOptInfo *index,
clausegroup_list = lappend(clausegroup_list, clausegroup);
indexcol++;
- classes++;
+ families++;
- } while (!DoneMatchingIndexKeys(classes));
+ } while (!DoneMatchingIndexKeys(families));
if (!*found_clause && !found_outer_clause)
return NIL; /* no indexable clauses anywhere */
@@ -937,7 +937,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
*
* (1) must be in the form (indexkey op const) or (const op indexkey);
* and
- * (2) must contain an operator which is in the same class as the index
+ * (2) must contain an operator which is in the same family as the index
* operator for this column, or is a "special" operator as recognized
* by match_special_index_operator().
*
@@ -978,7 +978,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
*
* 'index' is the index of interest.
* 'indexcol' is a column number of 'index' (counting from 0).
- * 'opclass' is the corresponding operator class.
+ * 'opfamily' is the corresponding operator family.
* 'rinfo' is the clause to be tested (as a RestrictInfo node).
* 'saop_control' indicates whether ScalarArrayOpExpr clauses can be used.
*
@@ -990,7 +990,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
static bool
match_clause_to_indexcol(IndexOptInfo *index,
int indexcol,
- Oid opclass,
+ Oid opfamily,
RestrictInfo *rinfo,
Relids outer_relids,
SaOpControl saop_control)
@@ -1013,7 +1013,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
return false;
/* First check for boolean-index cases. */
- if (IsBooleanOpclass(opclass))
+ if (IsBooleanOpfamily(opfamily))
{
if (match_boolean_index_clause((Node *) clause, indexcol, index))
return true;
@@ -1052,7 +1052,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
}
else if (clause && IsA(clause, RowCompareExpr))
{
- return match_rowcompare_to_indexcol(index, indexcol, opclass,
+ return match_rowcompare_to_indexcol(index, indexcol, opfamily,
(RowCompareExpr *) clause,
outer_relids);
}
@@ -1067,15 +1067,15 @@ match_clause_to_indexcol(IndexOptInfo *index,
bms_is_subset(right_relids, outer_relids) &&
!contain_volatile_functions(rightop))
{
- if (is_indexable_operator(expr_op, opclass, true))
+ if (is_indexable_operator(expr_op, opfamily, true))
return true;
/*
- * If we didn't find a member of the index's opclass, see whether it
+ * If we didn't find a member of the index's opfamily, see whether it
* is a "special" indexable operator.
*/
if (plain_op &&
- match_special_index_operator(clause, opclass, true))
+ match_special_index_operator(clause, opfamily, true))
return true;
return false;
}
@@ -1085,14 +1085,14 @@ match_clause_to_indexcol(IndexOptInfo *index,
bms_is_subset(left_relids, outer_relids) &&
!contain_volatile_functions(leftop))
{
- if (is_indexable_operator(expr_op, opclass, false))
+ if (is_indexable_operator(expr_op, opfamily, false))
return true;
/*
- * If we didn't find a member of the index's opclass, see whether it
+ * If we didn't find a member of the index's opfamily, see whether it
* is a "special" indexable operator.
*/
- if (match_special_index_operator(clause, opclass, false))
+ if (match_special_index_operator(clause, opfamily, false))
return true;
return false;
}
@@ -1102,14 +1102,14 @@ match_clause_to_indexcol(IndexOptInfo *index,
/*
* is_indexable_operator
- * Does the operator match the specified index opclass?
+ * Does the operator match the specified index opfamily?
*
* If the indexkey is on the right, what we actually want to know
* is whether the operator has a commutator operator that matches
- * the opclass.
+ * the opfamily.
*/
static bool
-is_indexable_operator(Oid expr_op, Oid opclass, bool indexkey_on_left)
+is_indexable_operator(Oid expr_op, Oid opfamily, bool indexkey_on_left)
{
/* Get the commuted operator if necessary */
if (!indexkey_on_left)
@@ -1119,8 +1119,8 @@ is_indexable_operator(Oid expr_op, Oid opclass, bool indexkey_on_left)
return false;
}
- /* OK if the (commuted) operator is a member of the index's opclass */
- return op_in_opclass(expr_op, opclass);
+ /* OK if the (commuted) operator is a member of the index's opfamily */
+ return op_in_opfamily(expr_op, opfamily);
}
/*
@@ -1131,7 +1131,7 @@ is_indexable_operator(Oid expr_op, Oid opclass, bool indexkey_on_left)
static bool
match_rowcompare_to_indexcol(IndexOptInfo *index,
int indexcol,
- Oid opclass,
+ Oid opfamily,
RowCompareExpr *clause,
Relids outer_relids)
{
@@ -1144,13 +1144,14 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
return false;
/*
- * We could do the matching on the basis of insisting that the opclass
- * shown in the RowCompareExpr be the same as the index column's opclass,
- * but that does not work well for cross-type comparisons (the opclass
- * could be for the other datatype). Also it would fail to handle indexes
- * using reverse-sort opclasses. Instead, match if the operator listed in
- * the RowCompareExpr is the < <= > or >= member of the index opclass
- * (after commutation, if the indexkey is on the right).
+ * We could do the matching on the basis of insisting that the opfamily
+ * shown in the RowCompareExpr be the same as the index column's opfamily,
+ * but that could fail in the presence of reverse-sort opfamilies: it'd
+ * be a matter of chance whether RowCompareExpr had picked the forward
+ * or reverse-sort family. So look only at the operator, and match
+ * if it is a member of the index's opfamily (after commutation, if the
+ * indexkey is on the right). We'll worry later about whether any
+ * additional operators are matchable to the index.
*/
leftop = (Node *) linitial(clause->largs);
rightop = (Node *) linitial(clause->rargs);
@@ -1177,8 +1178,8 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
else
return false;
- /* We're good if the operator is the right type of opclass member */
- switch (get_op_opclass_strategy(expr_op, opclass))
+ /* We're good if the operator is the right type of opfamily member */
+ switch (get_op_opfamily_strategy(expr_op, opfamily))
{
case BTLessStrategyNumber:
case BTLessEqualStrategyNumber:
@@ -1316,23 +1317,23 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids)
{
IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
int indexcol = 0;
- Oid *classes = index->classlist;
+ Oid *families = index->opfamily;
do
{
- Oid curClass = classes[0];
+ Oid curFamily = families[0];
if (match_clause_to_indexcol(index,
indexcol,
- curClass,
+ curFamily,
rinfo,
outer_relids,
SAOP_ALLOW))
return true;
indexcol++;
- classes++;
- } while (!DoneMatchingIndexKeys(classes));
+ families++;
+ } while (!DoneMatchingIndexKeys(families));
}
return false;
@@ -1601,11 +1602,11 @@ find_clauses_for_join(PlannerInfo *root, RelOptInfo *rel,
* Note: it would be possible to similarly ignore useless ORDER BY items;
* that is, an index on just y could be considered to match the ordering of
* ... WHERE x = 42 ORDER BY x, y;
- * But proving that this is safe would require finding a btree opclass
+ * But proving that this is safe would require finding a btree opfamily
* containing both the = operator and the < or > operator in the ORDER BY
* item. That's significantly more expensive than what we do here, since
* we'd have to look at restriction clauses unrelated to the current index
- * and search for opclasses without any hint from the index. The practical
+ * and search for opfamilies without any hint from the index. The practical
* use-cases seem to be mostly covered by ignoring index columns, so that's
* all we do for now.
*
@@ -1627,7 +1628,7 @@ match_variant_ordering(PlannerInfo *root,
/*
* Forget the whole thing if not a btree index; our check for ignorable
- * columns assumes we are dealing with btree opclasses. (It'd be possible
+ * columns assumes we are dealing with btree opfamilies. (It'd be possible
* to factor out just the try for backwards indexscan, but considering
* that we presently have no orderable indexes except btrees anyway, it's
* hardly worth contorting this code for that case.)
@@ -1685,7 +1686,7 @@ identify_ignorable_ordering_cols(PlannerInfo *root,
foreach(l, restrictclauses)
{
List *sublist = (List *) lfirst(l);
- Oid opclass = index->classlist[indexcol];
+ Oid opfamily = index->opfamily[indexcol];
ListCell *l2;
foreach(l2, sublist)
@@ -1698,7 +1699,7 @@ identify_ignorable_ordering_cols(PlannerInfo *root,
bool ispc;
/* First check for boolean-index cases. */
- if (IsBooleanOpclass(opclass))
+ if (IsBooleanOpfamily(opfamily))
{
if (match_boolean_index_clause((Node *) clause, indexcol,
index))
@@ -1729,18 +1730,18 @@ identify_ignorable_ordering_cols(PlannerInfo *root,
{
Assert(match_index_to_operand(lsecond(clause->args), indexcol,
index));
- /* Must flip operator to get the opclass member */
+ /* Must flip operator to get the opfamily member */
clause_op = get_commutator(clause_op);
varonleft = false;
}
if (!OidIsValid(clause_op))
continue; /* ignore non match, per next comment */
- op_strategy = get_op_opclass_strategy(clause_op, opclass);
+ op_strategy = get_op_opfamily_strategy(clause_op, opfamily);
/*
* You might expect to see Assert(op_strategy != 0) here, but you
* won't: the clause might contain a special indexable operator
- * rather than an ordinary opclass member. Currently none of the
+ * rather than an ordinary opfamily member. Currently none of the
* special operators are very likely to expand to an equality
* operator; we do not bother to check, but just assume no match.
*/
@@ -1968,7 +1969,7 @@ match_index_to_operand(Node *operand,
*
* match_special_index_operator() is just an auxiliary function for
* match_clause_to_indexcol(); after the latter fails to recognize a
- * restriction opclause's operator as a member of an index's opclass,
+ * restriction opclause's operator as a member of an index's opfamily,
* it asks match_special_index_operator() whether the clause should be
* considered an indexqual anyway.
*
@@ -1978,7 +1979,7 @@ match_index_to_operand(Node *operand,
* expand_indexqual_conditions() converts a list of lists of RestrictInfo
* nodes (with implicit AND semantics across list elements) into
* a list of clauses that the executor can actually handle. For operators
- * that are members of the index's opclass this transformation is a no-op,
+ * that are members of the index's opfamily this transformation is a no-op,
* but clauses recognized by match_special_index_operator() or
* match_boolean_index_clause() must be converted into one or more "regular"
* indexqual conditions.
@@ -1989,8 +1990,8 @@ match_index_to_operand(Node *operand,
* match_boolean_index_clause
* Recognize restriction clauses that can be matched to a boolean index.
*
- * This should be called only when IsBooleanOpclass() recognizes the
- * index's operator class. We check to see if the clause matches the
+ * This should be called only when IsBooleanOpfamily() recognizes the
+ * index's operator family. We check to see if the clause matches the
* index's key.
*/
static bool
@@ -2034,11 +2035,11 @@ match_boolean_index_clause(Node *clause,
*
* The given clause is already known to be a binary opclause having
* the form (indexkey OP pseudoconst) or (pseudoconst OP indexkey),
- * but the OP proved not to be one of the index's opclass operators.
+ * but the OP proved not to be one of the index's opfamily operators.
* Return 'true' if we can do something with it anyway.
*/
static bool
-match_special_index_operator(Expr *clause, Oid opclass,
+match_special_index_operator(Expr *clause, Oid opfamily,
bool indexkey_on_left)
{
bool isIndexable = false;
@@ -2122,12 +2123,12 @@ match_special_index_operator(Expr *clause, Oid opclass,
return false;
/*
- * Must also check that index's opclass supports the operators we will
+ * Must also check that index's opfamily supports the operators we will
* want to apply. (A hash index, for example, will not support ">=".)
* Currently, only btree supports the operators we need.
*
- * We insist on the opclass being the specific one we expect, else we'd do
- * the wrong thing if someone were to make a reverse-sort opclass with the
+ * We insist on the opfamily being the specific one we expect, else we'd do
+ * the wrong thing if someone were to make a reverse-sort opfamily with the
* same operators.
*/
switch (expr_op)
@@ -2136,12 +2137,9 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_TEXT_ICLIKE_OP:
case OID_TEXT_REGEXEQ_OP:
case OID_TEXT_ICREGEXEQ_OP:
- /* text operators will be used for varchar inputs, too */
isIndexable =
- (opclass == TEXT_PATTERN_BTREE_OPS_OID) ||
- (opclass == TEXT_BTREE_OPS_OID && lc_collate_is_c()) ||
- (opclass == VARCHAR_PATTERN_BTREE_OPS_OID) ||
- (opclass == VARCHAR_BTREE_OPS_OID && lc_collate_is_c());
+ (opfamily == TEXT_PATTERN_BTREE_FAM_OID) ||
+ (opfamily == TEXT_BTREE_FAM_OID && lc_collate_is_c());
break;
case OID_BPCHAR_LIKE_OP:
@@ -2149,8 +2147,8 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_BPCHAR_REGEXEQ_OP:
case OID_BPCHAR_ICREGEXEQ_OP:
isIndexable =
- (opclass == BPCHAR_PATTERN_BTREE_OPS_OID) ||
- (opclass == BPCHAR_BTREE_OPS_OID && lc_collate_is_c());
+ (opfamily == BPCHAR_PATTERN_BTREE_FAM_OID) ||
+ (opfamily == BPCHAR_BTREE_FAM_OID && lc_collate_is_c());
break;
case OID_NAME_LIKE_OP:
@@ -2158,18 +2156,17 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_NAME_REGEXEQ_OP:
case OID_NAME_ICREGEXEQ_OP:
isIndexable =
- (opclass == NAME_PATTERN_BTREE_OPS_OID) ||
- (opclass == NAME_BTREE_OPS_OID && lc_collate_is_c());
+ (opfamily == NAME_PATTERN_BTREE_FAM_OID) ||
+ (opfamily == NAME_BTREE_FAM_OID && lc_collate_is_c());
break;
case OID_BYTEA_LIKE_OP:
- isIndexable = (opclass == BYTEA_BTREE_OPS_OID);
+ isIndexable = (opfamily == BYTEA_BTREE_FAM_OID);
break;
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- isIndexable = (opclass == INET_BTREE_OPS_OID ||
- opclass == CIDR_BTREE_OPS_OID);
+ isIndexable = (opfamily == NETWORK_BTREE_FAM_OID);
break;
}
@@ -2180,7 +2177,7 @@ match_special_index_operator(Expr *clause, Oid opclass,
* expand_indexqual_conditions
* Given a list of sublists of RestrictInfo nodes, produce a flat list
* of index qual clauses. Standard qual clauses (those in the index's
- * opclass) are passed through unchanged. Boolean clauses and "special"
+ * opfamily) are passed through unchanged. Boolean clauses and "special"
* index operators are expanded into clauses that the indexscan machinery
* will know what to do with. RowCompare clauses are simplified if
* necessary to create a clause that is fully checkable by the index.
@@ -2196,7 +2193,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
List *resultquals = NIL;
ListCell *clausegroup_item;
int indexcol = 0;
- Oid *classes = index->classlist;
+ Oid *families = index->opfamily;
if (clausegroups == NIL)
return NIL;
@@ -2204,7 +2201,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
clausegroup_item = list_head(clausegroups);
do
{
- Oid curClass = classes[0];
+ Oid curFamily = families[0];
ListCell *l;
foreach(l, (List *) lfirst(clausegroup_item))
@@ -2213,7 +2210,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
Expr *clause = rinfo->clause;
/* First check for boolean cases */
- if (IsBooleanOpclass(curClass))
+ if (IsBooleanOpfamily(curFamily))
{
Expr *boolqual;
@@ -2240,7 +2237,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
{
resultquals = list_concat(resultquals,
expand_indexqual_opclause(rinfo,
- curClass));
+ curFamily));
}
else if (IsA(clause, ScalarArrayOpExpr))
{
@@ -2262,8 +2259,8 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
clausegroup_item = lnext(clausegroup_item);
indexcol++;
- classes++;
- } while (clausegroup_item != NULL && !DoneMatchingIndexKeys(classes));
+ families++;
+ } while (clausegroup_item != NULL && !DoneMatchingIndexKeys(families));
Assert(clausegroup_item == NULL); /* else more groups than indexkeys */
@@ -2337,7 +2334,7 @@ expand_boolean_index_clause(Node *clause,
* The input is a single RestrictInfo, the output a list of RestrictInfos
*/
static List *
-expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
+expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
{
Expr *clause = rinfo->clause;
@@ -2354,7 +2351,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
switch (expr_op)
{
/*
- * LIKE and regex operators are not members of any index opclass,
+ * LIKE and regex operators are not members of any index opfamily,
* so if we find one in an indexqual list we can assume that it
* was accepted by match_special_index_operator().
*/
@@ -2364,7 +2361,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
case OID_BYTEA_LIKE_OP:
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like,
&prefix, &rest);
- result = prefix_quals(leftop, opclass, prefix, pstatus);
+ result = prefix_quals(leftop, opfamily, prefix, pstatus);
break;
case OID_TEXT_ICLIKE_OP:
@@ -2373,7 +2370,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
/* the right-hand const is type text for all of these */
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
&prefix, &rest);
- result = prefix_quals(leftop, opclass, prefix, pstatus);
+ result = prefix_quals(leftop, opfamily, prefix, pstatus);
break;
case OID_TEXT_REGEXEQ_OP:
@@ -2382,7 +2379,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
/* the right-hand const is type text for all of these */
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex,
&prefix, &rest);
- result = prefix_quals(leftop, opclass, prefix, pstatus);
+ result = prefix_quals(leftop, opfamily, prefix, pstatus);
break;
case OID_TEXT_ICREGEXEQ_OP:
@@ -2391,12 +2388,12 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
/* the right-hand const is type text for all of these */
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
&prefix, &rest);
- result = prefix_quals(leftop, opclass, prefix, pstatus);
+ result = prefix_quals(leftop, opfamily, prefix, pstatus);
break;
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- result = network_prefix_quals(leftop, expr_op, opclass,
+ result = network_prefix_quals(leftop, expr_op, opfamily,
patt->constvalue);
break;
@@ -2416,7 +2413,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass)
* the specified column of the index. We can use additional columns of the
* row comparison as index qualifications, so long as they match the index
* in the "same direction", ie, the indexkeys are all on the same side of the
- * clause and the operators are all the same-type members of the opclasses.
+ * clause and the operators are all the same-type members of the opfamilies.
* If all the columns of the RowCompareExpr match in this way, we just use it
* as-is. Otherwise, we build a shortened RowCompareExpr (if more than one
* column matches) or a simple OpExpr (if the first-column match is all
@@ -2433,12 +2430,14 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
RowCompareExpr *clause = (RowCompareExpr *) rinfo->clause;
bool var_on_left;
int op_strategy;
- Oid op_subtype;
+ Oid op_lefttype;
+ Oid op_righttype;
bool op_recheck;
int matching_cols;
Oid expr_op;
- List *opclasses;
- List *subtypes;
+ List *opfamilies;
+ List *lefttypes;
+ List *righttypes;
List *new_ops;
ListCell *largs_cell;
ListCell *rargs_cell;
@@ -2453,11 +2452,15 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
expr_op = linitial_oid(clause->opnos);
if (!var_on_left)
expr_op = get_commutator(expr_op);
- get_op_opclass_properties(expr_op, index->classlist[indexcol],
- &op_strategy, &op_subtype, &op_recheck);
- /* Build lists of the opclasses and operator subtypes in case needed */
- opclasses = list_make1_oid(index->classlist[indexcol]);
- subtypes = list_make1_oid(op_subtype);
+ get_op_opfamily_properties(expr_op, index->opfamily[indexcol],
+ &op_strategy,
+ &op_lefttype,
+ &op_righttype,
+ &op_recheck);
+ /* Build lists of the opfamilies and operator datatypes in case needed */
+ opfamilies = list_make1_oid(index->opfamily[indexcol]);
+ lefttypes = list_make1_oid(op_lefttype);
+ righttypes = list_make1_oid(op_righttype);
/*
* See how many of the remaining columns match some index column in the
@@ -2513,15 +2516,19 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
break; /* no match found */
/* Now, do we have the right operator for this column? */
- if (get_op_opclass_strategy(expr_op, index->classlist[i])
+ if (get_op_opfamily_strategy(expr_op, index->opfamily[i])
!= op_strategy)
break;
- /* Add opclass and subtype to lists */
- get_op_opclass_properties(expr_op, index->classlist[i],
- &op_strategy, &op_subtype, &op_recheck);
- opclasses = lappend_oid(opclasses, index->classlist[i]);
- subtypes = lappend_oid(subtypes, op_subtype);
+ /* Add opfamily and datatypes to lists */
+ get_op_opfamily_properties(expr_op, index->opfamily[i],
+ &op_strategy,
+ &op_lefttype,
+ &op_righttype,
+ &op_recheck);
+ opfamilies = lappend_oid(opfamilies, index->opfamily[i]);
+ lefttypes = lappend_oid(lefttypes, op_lefttype);
+ righttypes = lappend_oid(righttypes, op_righttype);
/* This column matches, keep scanning */
matching_cols++;
@@ -2547,8 +2554,9 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
}
else
{
- ListCell *opclasses_cell;
- ListCell *subtypes_cell;
+ ListCell *opfamilies_cell;
+ ListCell *lefttypes_cell;
+ ListCell *righttypes_cell;
if (op_strategy == BTLessStrategyNumber)
op_strategy = BTLessEqualStrategyNumber;
@@ -2557,23 +2565,30 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
else
elog(ERROR, "unexpected strategy number %d", op_strategy);
new_ops = NIL;
- forboth(opclasses_cell, opclasses, subtypes_cell, subtypes)
+ lefttypes_cell = list_head(lefttypes);
+ righttypes_cell = list_head(righttypes);
+ foreach(opfamilies_cell, opfamilies)
{
- expr_op = get_opclass_member(lfirst_oid(opclasses_cell),
- lfirst_oid(subtypes_cell),
- op_strategy);
+ Oid opfam = lfirst_oid(opfamilies_cell);
+ Oid lefttype = lfirst_oid(lefttypes_cell);
+ Oid righttype = lfirst_oid(righttypes_cell);
+
+ expr_op = get_opfamily_member(opfam, lefttype, righttype,
+ op_strategy);
if (!OidIsValid(expr_op)) /* should not happen */
- elog(ERROR, "could not find member %d of opclass %u",
- op_strategy, lfirst_oid(opclasses_cell));
+ elog(ERROR, "could not find member %d(%u,%u) of opfamily %u",
+ op_strategy, lefttype, righttype, opfam);
if (!var_on_left)
{
expr_op = get_commutator(expr_op);
if (!OidIsValid(expr_op)) /* should not happen */
- elog(ERROR, "could not find commutator of member %d of opclass %u",
- op_strategy, lfirst_oid(opclasses_cell));
+ elog(ERROR, "could not find commutator of member %d(%u,%u) of opfamily %u",
+ op_strategy, lefttype, righttype, opfam);
}
new_ops = lappend_oid(new_ops, expr_op);
}
+ lefttypes_cell = lnext(lefttypes_cell);
+ righttypes_cell = lnext(righttypes_cell);
}
/* If we have more than one matching col, create a subset rowcompare */
@@ -2587,8 +2602,8 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
rc->rctype = (op_strategy == BTLessEqualStrategyNumber) ?
ROWCOMPARE_GE : ROWCOMPARE_LE;
rc->opnos = new_ops;
- rc->opclasses = list_truncate(list_copy(clause->opclasses),
- matching_cols);
+ rc->opfamilies = list_truncate(list_copy(clause->opfamilies),
+ matching_cols);
rc->largs = list_truncate((List *) copyObject(clause->largs),
matching_cols);
rc->rargs = list_truncate((List *) copyObject(clause->rargs),
@@ -2608,12 +2623,12 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
/*
* Given a fixed prefix that all the "leftop" values must have,
- * generate suitable indexqual condition(s). opclass is the index
- * operator class; we use it to deduce the appropriate comparison
+ * generate suitable indexqual condition(s). opfamily is the index
+ * operator family; we use it to deduce the appropriate comparison
* operators and operand datatypes.
*/
static List *
-prefix_quals(Node *leftop, Oid opclass,
+prefix_quals(Node *leftop, Oid opfamily,
Const *prefix_const, Pattern_Prefix_Status pstatus)
{
List *result;
@@ -2624,35 +2639,30 @@ prefix_quals(Node *leftop, Oid opclass,
Assert(pstatus != Pattern_Prefix_None);
- switch (opclass)
+ switch (opfamily)
{
- case TEXT_BTREE_OPS_OID:
- case TEXT_PATTERN_BTREE_OPS_OID:
+ case TEXT_BTREE_FAM_OID:
+ case TEXT_PATTERN_BTREE_FAM_OID:
datatype = TEXTOID;
break;
- case VARCHAR_BTREE_OPS_OID:
- case VARCHAR_PATTERN_BTREE_OPS_OID:
- datatype = VARCHAROID;
- break;
-
- case BPCHAR_BTREE_OPS_OID:
- case BPCHAR_PATTERN_BTREE_OPS_OID:
+ case BPCHAR_BTREE_FAM_OID:
+ case BPCHAR_PATTERN_BTREE_FAM_OID:
datatype = BPCHAROID;
break;
- case NAME_BTREE_OPS_OID:
- case NAME_PATTERN_BTREE_OPS_OID:
+ case NAME_BTREE_FAM_OID:
+ case NAME_PATTERN_BTREE_FAM_OID:
datatype = NAMEOID;
break;
- case BYTEA_BTREE_OPS_OID:
+ case BYTEA_BTREE_FAM_OID:
datatype = BYTEAOID;
break;
default:
/* shouldn't get here */
- elog(ERROR, "unexpected opclass: %u", opclass);
+ elog(ERROR, "unexpected opfamily: %u", opfamily);
return NIL;
}
@@ -2688,10 +2698,10 @@ prefix_quals(Node *leftop, Oid opclass,
*/
if (pstatus == Pattern_Prefix_Exact)
{
- oproid = get_opclass_member(opclass, InvalidOid,
- BTEqualStrategyNumber);
+ oproid = get_opfamily_member(opfamily, datatype, datatype,
+ BTEqualStrategyNumber);
if (oproid == InvalidOid)
- elog(ERROR, "no = operator for opclass %u", opclass);
+ elog(ERROR, "no = operator for opfamily %u", opfamily);
expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftop, (Expr *) prefix_const);
result = list_make1(make_restrictinfo(expr, true, false, false, NULL));
@@ -2703,10 +2713,10 @@ prefix_quals(Node *leftop, Oid opclass,
*
* We can always say "x >= prefix".
*/
- oproid = get_opclass_member(opclass, InvalidOid,
- BTGreaterEqualStrategyNumber);
+ oproid = get_opfamily_member(opfamily, datatype, datatype,
+ BTGreaterEqualStrategyNumber);
if (oproid == InvalidOid)
- elog(ERROR, "no >= operator for opclass %u", opclass);
+ elog(ERROR, "no >= operator for opfamily %u", opfamily);
expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftop, (Expr *) prefix_const);
result = list_make1(make_restrictinfo(expr, true, false, false, NULL));
@@ -2719,10 +2729,10 @@ prefix_quals(Node *leftop, Oid opclass,
greaterstr = make_greater_string(prefix_const);
if (greaterstr)
{
- oproid = get_opclass_member(opclass, InvalidOid,
- BTLessStrategyNumber);
+ oproid = get_opfamily_member(opfamily, datatype, datatype,
+ BTLessStrategyNumber);
if (oproid == InvalidOid)
- elog(ERROR, "no < operator for opclass %u", opclass);
+ elog(ERROR, "no < operator for opfamily %u", opfamily);
expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftop, (Expr *) greaterstr);
result = lappend(result,
@@ -2733,12 +2743,12 @@ prefix_quals(Node *leftop, Oid opclass,
}
/*
- * Given a leftop and a rightop, and a inet-class sup/sub operator,
+ * Given a leftop and a rightop, and a inet-family sup/sub operator,
* generate suitable indexqual condition(s). expr_op is the original
- * operator, and opclass is the index opclass.
+ * operator, and opfamily is the index opfamily.
*/
static List *
-network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
+network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
{
bool is_eq;
Oid datatype;
@@ -2770,17 +2780,17 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
*/
if (is_eq)
{
- opr1oid = get_opclass_member(opclass, InvalidOid,
- BTGreaterEqualStrategyNumber);
+ opr1oid = get_opfamily_member(opfamily, datatype, datatype,
+ BTGreaterEqualStrategyNumber);
if (opr1oid == InvalidOid)
- elog(ERROR, "no >= operator for opclass %u", opclass);
+ elog(ERROR, "no >= operator for opfamily %u", opfamily);
}
else
{
- opr1oid = get_opclass_member(opclass, InvalidOid,
- BTGreaterStrategyNumber);
+ opr1oid = get_opfamily_member(opfamily, datatype, datatype,
+ BTGreaterStrategyNumber);
if (opr1oid == InvalidOid)
- elog(ERROR, "no > operator for opclass %u", opclass);
+ elog(ERROR, "no > operator for opfamily %u", opfamily);
}
opr1right = network_scan_first(rightop);
@@ -2793,10 +2803,10 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
/* create clause "key <= network_scan_last( rightop )" */
- opr2oid = get_opclass_member(opclass, InvalidOid,
- BTLessEqualStrategyNumber);
+ opr2oid = get_opfamily_member(opfamily, datatype, datatype,
+ BTLessEqualStrategyNumber);
if (opr2oid == InvalidOid)
- elog(ERROR, "no <= operator for opclass %u", opclass);
+ elog(ERROR, "no <= operator for opfamily %u", opfamily);
opr2right = network_scan_last(rightop);
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 6882439ca3a..06022b373b5 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.107 2006/10/04 00:29:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.108 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
#include <math.h>
+#include "access/skey.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
@@ -39,6 +40,8 @@ static List *select_mergejoin_clauses(RelOptInfo *joinrel,
RelOptInfo *innerrel,
List *restrictlist,
JoinType jointype);
+static void build_mergejoin_strat_lists(List *mergeclauses,
+ List **mergefamilies, List **mergestrategies);
/*
@@ -225,6 +228,8 @@ sort_inner_and_outer(PlannerInfo *root,
List *front_pathkey = (List *) lfirst(l);
List *cur_pathkeys;
List *cur_mergeclauses;
+ List *mergefamilies;
+ List *mergestrategies;
List *outerkeys;
List *innerkeys;
List *merge_pathkeys;
@@ -269,6 +274,10 @@ sort_inner_and_outer(PlannerInfo *root,
merge_pathkeys = build_join_pathkeys(root, joinrel, jointype,
outerkeys);
+ /* Build opfamily info for execution */
+ build_mergejoin_strat_lists(cur_mergeclauses,
+ &mergefamilies, &mergestrategies);
+
/*
* And now we can make the path.
*/
@@ -281,6 +290,8 @@ sort_inner_and_outer(PlannerInfo *root,
restrictlist,
merge_pathkeys,
cur_mergeclauses,
+ mergefamilies,
+ mergestrategies,
outerkeys,
innerkeys));
}
@@ -410,6 +421,8 @@ match_unsorted_outer(PlannerInfo *root,
Path *outerpath = (Path *) lfirst(l);
List *merge_pathkeys;
List *mergeclauses;
+ List *mergefamilies;
+ List *mergestrategies;
List *innersortkeys;
List *trialsortkeys;
Path *cheapest_startup_inner;
@@ -516,6 +529,10 @@ match_unsorted_outer(PlannerInfo *root,
mergeclauses,
innerrel);
+ /* Build opfamily info for execution */
+ build_mergejoin_strat_lists(mergeclauses,
+ &mergefamilies, &mergestrategies);
+
/*
* Generate a mergejoin on the basis of sorting the cheapest inner.
* Since a sort will be needed, only cheapest total cost matters. (But
@@ -531,6 +548,8 @@ match_unsorted_outer(PlannerInfo *root,
restrictlist,
merge_pathkeys,
mergeclauses,
+ mergefamilies,
+ mergestrategies,
NIL,
innersortkeys));
@@ -589,6 +608,11 @@ match_unsorted_outer(PlannerInfo *root,
}
else
newclauses = mergeclauses;
+
+ /* Build opfamily info for execution */
+ build_mergejoin_strat_lists(newclauses,
+ &mergefamilies, &mergestrategies);
+
add_path(joinrel, (Path *)
create_mergejoin_path(root,
joinrel,
@@ -598,6 +622,8 @@ match_unsorted_outer(PlannerInfo *root,
restrictlist,
merge_pathkeys,
newclauses,
+ mergefamilies,
+ mergestrategies,
NIL,
NIL));
cheapest_total_inner = innerpath;
@@ -633,6 +659,11 @@ match_unsorted_outer(PlannerInfo *root,
else
newclauses = mergeclauses;
}
+
+ /* Build opfamily info for execution */
+ build_mergejoin_strat_lists(newclauses,
+ &mergefamilies, &mergestrategies);
+
add_path(joinrel, (Path *)
create_mergejoin_path(root,
joinrel,
@@ -642,6 +673,8 @@ match_unsorted_outer(PlannerInfo *root,
restrictlist,
merge_pathkeys,
newclauses,
+ mergefamilies,
+ mergestrategies,
NIL,
NIL));
}
@@ -946,3 +979,35 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
return result_list;
}
+
+/*
+ * Temporary hack to build opfamily and strategy lists needed for mergejoin
+ * by the executor. We need to rethink the planner's handling of merge
+ * planning so that it can deal with multiple possible merge orders, but
+ * that's not done yet.
+ */
+static void
+build_mergejoin_strat_lists(List *mergeclauses,
+ List **mergefamilies, List **mergestrategies)
+{
+ ListCell *l;
+
+ *mergefamilies = NIL;
+ *mergestrategies = NIL;
+
+ foreach(l, mergeclauses)
+ {
+ RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
+
+ /*
+ * We do not need to worry about whether the mergeclause will be
+ * commuted at runtime --- it's the same opfamily either way.
+ */
+ *mergefamilies = lappend_oid(*mergefamilies, restrictinfo->mergeopfamily);
+ /*
+ * For the moment, strategy must always be LessThan --- see
+ * hack version of get_op_mergejoin_info
+ */
+ *mergestrategies = lappend_int(*mergestrategies, BTLessStrategyNumber);
+ }
+}
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 14f1f1a10f4..f924994480b 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.217 2006/10/04 00:29:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.218 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,7 +73,7 @@ static void fix_indexqual_references(List *indexquals, IndexPath *index_path,
List **indexstrategy,
List **indexsubtype);
static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index,
- Oid *opclass);
+ Oid *opfamily);
static List *get_switched_clauses(List *clauses, Relids outerrelids);
static List *order_qual_clauses(PlannerInfo *root, List *clauses);
static void copy_path_costsize(Plan *dest, Path *src);
@@ -113,7 +113,7 @@ static HashJoin *make_hashjoin(List *tlist,
static Hash *make_hash(Plan *lefttree);
static MergeJoin *make_mergejoin(List *tlist,
List *joinclauses, List *otherclauses,
- List *mergeclauses,
+ List *mergeclauses, List *mergefamilies, List *mergestrategies,
Plan *lefttree, Plan *righttree,
JoinType jointype);
static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
@@ -1540,6 +1540,8 @@ create_mergejoin_plan(PlannerInfo *root,
joinclauses,
otherclauses,
mergeclauses,
+ best_path->path_mergefamilies,
+ best_path->path_mergestrategies,
outer_plan,
inner_plan,
best_path->jpath.jointype);
@@ -1676,9 +1678,10 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
Expr *clause;
Oid clause_op;
- Oid opclass;
+ Oid opfamily;
int stratno;
- Oid stratsubtype;
+ Oid stratlefttype;
+ Oid stratrighttype;
bool recheck;
Assert(IsA(rinfo, RestrictInfo));
@@ -1709,11 +1712,11 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
/*
* Now, determine which index attribute this is, change the
- * indexkey operand as needed, and get the index opclass.
+ * indexkey operand as needed, and get the index opfamily.
*/
linitial(op->args) = fix_indexqual_operand(linitial(op->args),
index,
- &opclass);
+ &opfamily);
clause_op = op->opno;
}
else if (IsA(clause, RowCompareExpr))
@@ -1734,20 +1737,20 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
* For each column in the row comparison, determine which index
* attribute this is and change the indexkey operand as needed.
*
- * Save the index opclass for only the first column. We will
- * return the operator and opclass info for just the first column
+ * Save the index opfamily for only the first column. We will
+ * return the operator and opfamily info for just the first column
* of the row comparison; the executor will have to look up the
* rest if it needs them.
*/
foreach(lc, rc->largs)
{
- Oid tmp_opclass;
+ Oid tmp_opfamily;
lfirst(lc) = fix_indexqual_operand(lfirst(lc),
index,
- &tmp_opclass);
+ &tmp_opfamily);
if (lc == list_head(rc->largs))
- opclass = tmp_opclass;
+ opfamily = tmp_opfamily;
}
clause_op = linitial_oid(rc->opnos);
}
@@ -1759,11 +1762,11 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
/*
* Now, determine which index attribute this is, change the
- * indexkey operand as needed, and get the index opclass.
+ * indexkey operand as needed, and get the index opfamily.
*/
linitial(saop->args) = fix_indexqual_operand(linitial(saop->args),
index,
- &opclass);
+ &opfamily);
clause_op = saop->opno;
}
else
@@ -1776,15 +1779,18 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
*fixed_indexquals = lappend(*fixed_indexquals, clause);
/*
- * Look up the (possibly commuted) operator in the operator class to
- * get its strategy numbers and the recheck indicator. This also
+ * Look up the (possibly commuted) operator in the operator family to
+ * get its strategy number and the recheck indicator. This also
* double-checks that we found an operator matching the index.
*/
- get_op_opclass_properties(clause_op, opclass,
- &stratno, &stratsubtype, &recheck);
+ get_op_opfamily_properties(clause_op, opfamily,
+ &stratno,
+ &stratlefttype,
+ &stratrighttype,
+ &recheck);
*indexstrategy = lappend_int(*indexstrategy, stratno);
- *indexsubtype = lappend_oid(*indexsubtype, stratsubtype);
+ *indexsubtype = lappend_oid(*indexsubtype, stratrighttype);
/* If it's not lossy, add to nonlossy_indexquals */
if (!recheck)
@@ -1793,7 +1799,7 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path,
}
static Node *
-fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass)
+fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opfamily)
{
/*
* We represent index keys by Var nodes having the varno of the base table
@@ -1826,8 +1832,8 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass)
{
result = (Var *) copyObject(node);
result->varattno = pos + 1;
- /* return the correct opclass, too */
- *opclass = index->classlist[pos];
+ /* return the correct opfamily, too */
+ *opfamily = index->opfamily[pos];
return (Node *) result;
}
}
@@ -1853,8 +1859,8 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass)
result = makeVar(index->rel->relid, pos + 1,
exprType(lfirst(indexpr_item)), -1,
0);
- /* return the correct opclass, too */
- *opclass = index->classlist[pos];
+ /* return the correct opfamily, too */
+ *opfamily = index->opfamily[pos];
return (Node *) result;
}
indexpr_item = lnext(indexpr_item);
@@ -1863,7 +1869,7 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass)
/* Ooops... */
elog(ERROR, "node is not an index attribute");
- *opclass = InvalidOid; /* keep compiler quiet */
+ *opfamily = InvalidOid; /* keep compiler quiet */
return NULL;
}
@@ -2327,6 +2333,8 @@ make_mergejoin(List *tlist,
List *joinclauses,
List *otherclauses,
List *mergeclauses,
+ List *mergefamilies,
+ List *mergestrategies,
Plan *lefttree,
Plan *righttree,
JoinType jointype)
@@ -2340,6 +2348,8 @@ make_mergejoin(List *tlist,
plan->lefttree = lefttree;
plan->righttree = righttree;
node->mergeclauses = mergeclauses;
+ node->mergefamilies = mergefamilies;
+ node->mergestrategies = mergestrategies;
node->join.jointype = jointype;
node->join.joinqual = joinclauses;
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index da321a637b2..229b779af03 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.124 2006/12/07 19:33:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.125 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1109,10 +1109,10 @@ process_implied_equality(PlannerInfo *root,
/*
* Let's just make sure this appears to be a compatible operator.
+ *
+ * XXX needs work
*/
- if (pgopform->oprlsortop != sortop1 ||
- pgopform->oprrsortop != sortop2 ||
- pgopform->oprresult != BOOLOID)
+ if (pgopform->oprresult != BOOLOID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("equality operator for types %s and %s should be merge-joinable, but isn't",
@@ -1276,6 +1276,7 @@ check_mergejoinable(RestrictInfo *restrictinfo)
Oid opno,
leftOp,
rightOp;
+ Oid opfamily;
if (restrictinfo->pseudoconstant)
return;
@@ -1286,14 +1287,17 @@ check_mergejoinable(RestrictInfo *restrictinfo)
opno = ((OpExpr *) clause)->opno;
- if (op_mergejoinable(opno,
- &leftOp,
- &rightOp) &&
+ if (op_mergejoinable(opno) &&
!contain_volatile_functions((Node *) clause))
{
- restrictinfo->mergejoinoperator = opno;
- restrictinfo->left_sortop = leftOp;
- restrictinfo->right_sortop = rightOp;
+ /* XXX for the moment, continue to force use of particular sortops */
+ if (get_op_mergejoin_info(opno, &leftOp, &rightOp, &opfamily))
+ {
+ restrictinfo->mergejoinoperator = opno;
+ restrictinfo->left_sortop = leftOp;
+ restrictinfo->right_sortop = rightOp;
+ restrictinfo->mergeopfamily = opfamily;
+ }
}
}
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index e64340ed21c..fcc8d510786 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.22 2006/10/04 00:29:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.23 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -340,8 +340,8 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info)
Assert(is_opclause(rinfo->clause));
strategy =
- get_op_opclass_strategy(((OpExpr *) rinfo->clause)->opno,
- index->classlist[prevcol]);
+ get_op_opfamily_strategy(((OpExpr *) rinfo->clause)->opno,
+ index->opfamily[prevcol]);
if (strategy == BTEqualStrategyNumber)
break;
}
@@ -390,10 +390,10 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info)
* Does an aggregate match an index column?
*
* It matches if its argument is equal to the index column's data and its
- * sortop is either the LessThan or GreaterThan member of the column's opclass.
+ * sortop is either a LessThan or GreaterThan member of the column's opfamily.
*
- * We return ForwardScanDirection if match the LessThan member,
- * BackwardScanDirection if match the GreaterThan member,
+ * We return ForwardScanDirection if match a LessThan member,
+ * BackwardScanDirection if match a GreaterThan member,
* and NoMovementScanDirection if there's no match.
*/
static ScanDirection
@@ -405,9 +405,9 @@ match_agg_to_index_col(MinMaxAggInfo *info, IndexOptInfo *index, int indexcol)
if (!match_index_to_operand((Node *) info->target, indexcol, index))
return NoMovementScanDirection;
- /* Look up the operator in the opclass */
- strategy = get_op_opclass_strategy(info->aggsortop,
- index->classlist[indexcol]);
+ /* Look up the operator in the opfamily */
+ strategy = get_op_opfamily_strategy(info->aggsortop,
+ index->opfamily[indexcol]);
if (strategy == BTLessStrategyNumber)
return ForwardScanDirection;
if (strategy == BTGreaterStrategyNumber)
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 7793d071cda..f42a28cddd5 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.114 2006/12/10 22:13:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.115 2006/12/23 00:43:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -689,11 +689,11 @@ convert_IN_to_join(PlannerInfo *root, SubLink *sublink)
return NULL;
if (sublink->testexpr && IsA(sublink->testexpr, OpExpr))
{
- List *opclasses;
+ List *opfamilies;
List *opstrats;
get_op_btree_interpretation(((OpExpr *) sublink->testexpr)->opno,
- &opclasses, &opstrats);
+ &opfamilies, &opstrats);
if (!list_member_int(opstrats, ROWCOMPARE_EQ))
return NULL;
}
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 73ad926418f..0f720c40e93 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.224 2006/12/21 16:05:13 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.225 2006/12/23 00:43:10 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1294,13 +1294,9 @@ CommuteRowCompareExpr(RowCompareExpr *clause)
clause->opnos = newops;
/*
- * Note: we don't bother to update the opclasses list, but just set it to
- * empty. This is OK since this routine is currently only used for index
- * quals, and the index machinery won't use the opclass information. The
- * original opclass list is NOT valid if we have commuted any cross-type
- * comparisons, so don't leave it in place.
+ * Note: we need not change the opfamilies list; we assume any btree
+ * opfamily containing an operator will also contain its commutator.
*/
- clause->opclasses = NIL; /* XXX */
temp = clause->largs;
clause->largs = clause->rargs;
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 01f3151bee8..5042a3ff563 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.133 2006/10/04 00:29:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.134 2006/12/23 00:43:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1152,6 +1152,10 @@ create_nestloop_path(PlannerInfo *root,
* 'pathkeys' are the path keys of the new join path
* 'mergeclauses' are the RestrictInfo nodes to use as merge clauses
* (this should be a subset of the restrict_clauses list)
+ * 'mergefamilies' are the btree opfamily OIDs identifying the merge
+ * ordering for each merge clause
+ * 'mergestrategies' are the btree operator strategies identifying the merge
+ * ordering for each merge clause
* 'outersortkeys' are the sort varkeys for the outer relation
* 'innersortkeys' are the sort varkeys for the inner relation
*/
@@ -1164,6 +1168,8 @@ create_mergejoin_path(PlannerInfo *root,
List *restrict_clauses,
List *pathkeys,
List *mergeclauses,
+ List *mergefamilies,
+ List *mergestrategies,
List *outersortkeys,
List *innersortkeys)
{
@@ -1204,6 +1210,8 @@ create_mergejoin_path(PlannerInfo *root,
pathnode->jpath.joinrestrictinfo = restrict_clauses;
pathnode->jpath.path.pathkeys = pathkeys;
pathnode->path_mergeclauses = mergeclauses;
+ pathnode->path_mergefamilies = mergefamilies;
+ pathnode->path_mergestrategies = mergestrategies;
pathnode->outersortkeys = outersortkeys;
pathnode->innersortkeys = innersortkeys;
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 70a77bd3bd8..5b80991aefe 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.128 2006/12/18 18:56:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.129 2006/12/23 00:43:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -169,16 +169,16 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
info->ncolumns = ncolumns = index->indnatts;
/*
- * Need to make classlist and ordering arrays large enough to put
+ * Need to make opfamily and ordering arrays large enough to put
* a terminating 0 at the end of each one.
*/
info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
- info->classlist = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1));
+ info->opfamily = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1));
info->ordering = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1));
for (i = 0; i < ncolumns; i++)
{
- info->classlist[i] = indexRelation->rd_indclass->values[i];
+ info->opfamily[i] = indexRelation->rd_opfamily[i];
info->indexkeys[i] = index->indkey.values[i];
}
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 4a2609a4ab6..5f81cae4e85 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.10 2006/10/04 00:29:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.11 2006/12/23 00:43:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -939,7 +939,7 @@ arrayexpr_cleanup_fn(PredIterInfo info)
* already known immutable, so the clause will certainly always fail.)
*
* Finally, we may be able to deduce something using knowledge about btree
- * operator classes; this is encapsulated in btree_predicate_proof().
+ * operator families; this is encapsulated in btree_predicate_proof().
*----------
*/
static bool
@@ -989,7 +989,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
* that has "foo" as an input. See notes for implication case.
*
* Finally, we may be able to deduce something using knowledge about btree
- * operator classes; this is encapsulated in btree_predicate_proof().
+ * operator families; this is encapsulated in btree_predicate_proof().
*----------
*/
static bool
@@ -1062,8 +1062,8 @@ extract_not_arg(Node *clause)
* The strategy numbers defined by btree indexes (see access/skey.h) are:
* (1) < (2) <= (3) = (4) >= (5) >
* and in addition we use (6) to represent <>. <> is not a btree-indexable
- * operator, but we assume here that if the equality operator of a btree
- * opclass has a negator operator, the negator behaves as <> for the opclass.
+ * operator, but we assume here that if an equality operator of a btree
+ * opfamily has a negator operator, the negator behaves as <> for the opfamily.
*
* The interpretation of:
*
@@ -1146,10 +1146,10 @@ static const StrategyNumber BT_refute_table[6][6] = {
* What we look for here is binary boolean opclauses of the form
* "foo op constant", where "foo" is the same in both clauses. The operators
* and constants can be different but the operators must be in the same btree
- * operator class. We use the above operator implication tables to
+ * operator family. We use the above operator implication tables to
* derive implications between nonidentical clauses. (Note: "foo" is known
* immutable, and constants are surely immutable, but we have to check that
- * the operators are too. As of 8.0 it's possible for opclasses to contain
+ * the operators are too. As of 8.0 it's possible for opfamilies to contain
* operators that are merely stable, and we dare not make deductions with
* these.)
*----------
@@ -1171,12 +1171,12 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
pred_op_negator,
clause_op_negator,
test_op = InvalidOid;
- Oid opclass_id;
+ Oid opfamily_id;
bool found = false;
StrategyNumber pred_strategy,
clause_strategy,
test_strategy;
- Oid clause_subtype;
+ Oid clause_righttype;
Expr *test_expr;
ExprState *test_exprstate;
Datum test_result;
@@ -1272,28 +1272,30 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
}
/*
- * Try to find a btree opclass containing the needed operators.
+ * Try to find a btree opfamily containing the needed operators.
*
- * We must find a btree opclass that contains both operators, else the
+ * XXX this needs work!!!!!!!!!!!!!!!!!!!!!!!
+ *
+ * We must find a btree opfamily that contains both operators, else the
* implication can't be determined. Also, the pred_op has to be of
* default subtype (implying left and right input datatypes are the same);
* otherwise it's unsafe to put the pred_const on the left side of the
- * test. Also, the opclass must contain a suitable test operator matching
+ * test. Also, the opfamily must contain a suitable test operator matching
* the clause_const's type (which we take to mean that it has the same
* subtype as the original clause_operator).
*
- * If there are multiple matching opclasses, assume we can use any one to
+ * If there are multiple matching opfamilies, assume we can use any one to
* determine the logical relationship of the two operators and the correct
* corresponding test operator. This should work for any logically
- * consistent opclasses.
+ * consistent opfamilies.
*/
catlist = SearchSysCacheList(AMOPOPID, 1,
ObjectIdGetDatum(pred_op),
0, 0, 0);
/*
- * If we couldn't find any opclass containing the pred_op, perhaps it is a
- * <> operator. See if it has a negator that is in an opclass.
+ * If we couldn't find any opfamily containing the pred_op, perhaps it is a
+ * <> operator. See if it has a negator that is in an opfamily.
*/
pred_op_negated = false;
if (catlist->n_members == 0)
@@ -1312,23 +1314,22 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
/* Also may need the clause_op's negator */
clause_op_negator = get_negator(clause_op);
- /* Now search the opclasses */
+ /* Now search the opfamilies */
for (i = 0; i < catlist->n_members; i++)
{
HeapTuple pred_tuple = &catlist->members[i]->tuple;
Form_pg_amop pred_form = (Form_pg_amop) GETSTRUCT(pred_tuple);
HeapTuple clause_tuple;
- opclass_id = pred_form->amopclaid;
-
/* must be btree */
- if (!opclass_is_btree(opclass_id))
+ if (pred_form->amopmethod != BTREE_AM_OID)
continue;
- /* predicate operator must be default within this opclass */
- if (pred_form->amopsubtype != InvalidOid)
+ /* predicate operator must be default within this opfamily */
+ if (pred_form->amoplefttype != pred_form->amoprighttype)
continue;
/* Get the predicate operator's btree strategy number */
+ opfamily_id = pred_form->amopfamily;
pred_strategy = (StrategyNumber) pred_form->amopstrategy;
Assert(pred_strategy >= 1 && pred_strategy <= 5);
@@ -1341,37 +1342,39 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
}
/*
- * From the same opclass, find a strategy number for the clause_op, if
- * possible
+ * From the same opfamily, find a strategy number for the clause_op,
+ * if possible
*/
clause_tuple = SearchSysCache(AMOPOPID,
ObjectIdGetDatum(clause_op),
- ObjectIdGetDatum(opclass_id),
+ ObjectIdGetDatum(opfamily_id),
0, 0);
if (HeapTupleIsValid(clause_tuple))
{
Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple);
- /* Get the restriction clause operator's strategy/subtype */
+ /* Get the restriction clause operator's strategy/datatype */
clause_strategy = (StrategyNumber) clause_form->amopstrategy;
Assert(clause_strategy >= 1 && clause_strategy <= 5);
- clause_subtype = clause_form->amopsubtype;
+ Assert(clause_form->amoplefttype == pred_form->amoplefttype);
+ clause_righttype = clause_form->amoprighttype;
ReleaseSysCache(clause_tuple);
}
else if (OidIsValid(clause_op_negator))
{
clause_tuple = SearchSysCache(AMOPOPID,
ObjectIdGetDatum(clause_op_negator),
- ObjectIdGetDatum(opclass_id),
+ ObjectIdGetDatum(opfamily_id),
0, 0);
if (HeapTupleIsValid(clause_tuple))
{
Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple);
- /* Get the restriction clause operator's strategy/subtype */
+ /* Get the restriction clause operator's strategy/datatype */
clause_strategy = (StrategyNumber) clause_form->amopstrategy;
Assert(clause_strategy >= 1 && clause_strategy <= 5);
- clause_subtype = clause_form->amopsubtype;
+ Assert(clause_form->amoplefttype == pred_form->amoplefttype);
+ clause_righttype = clause_form->amoprighttype;
ReleaseSysCache(clause_tuple);
/* Only consider negators that are = */
@@ -1400,20 +1403,24 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
}
/*
- * See if opclass has an operator for the test strategy and the clause
- * datatype.
+ * See if opfamily has an operator for the test strategy and the
+ * datatypes.
*/
if (test_strategy == BTNE)
{
- test_op = get_opclass_member(opclass_id, clause_subtype,
- BTEqualStrategyNumber);
+ test_op = get_opfamily_member(opfamily_id,
+ pred_form->amoprighttype,
+ clause_righttype,
+ BTEqualStrategyNumber);
if (OidIsValid(test_op))
test_op = get_negator(test_op);
}
else
{
- test_op = get_opclass_member(opclass_id, clause_subtype,
- test_strategy);
+ test_op = get_opfamily_member(opfamily_id,
+ pred_form->amoprighttype,
+ clause_righttype,
+ test_strategy);
}
if (OidIsValid(test_op))
{
@@ -1423,7 +1430,7 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
* Note that we require only the test_op to be immutable, not the
* original clause_op. (pred_op is assumed to have been checked
* immutable by the caller.) Essentially we are assuming that the
- * opclass is consistent even if it contains operators that are
+ * opfamily is consistent even if it contains operators that are
* merely stable.
*/
if (op_volatile(test_op) == PROVOLATILE_IMMUTABLE)
@@ -1438,7 +1445,7 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
if (!found)
{
- /* couldn't find a btree opclass to interpret the operators */
+ /* couldn't find a btree opfamily to interpret the operators */
return false;
}
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index 9176ae1680c..adfd9e47858 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.49 2006/10/04 00:29:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.50 2006/12/23 00:43:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -342,6 +342,7 @@ make_restrictinfo_internal(Expr *clause,
restrictinfo->mergejoinoperator = InvalidOid;
restrictinfo->left_sortop = InvalidOid;
restrictinfo->right_sortop = InvalidOid;
+ restrictinfo->mergeopfamily = InvalidOid;
restrictinfo->left_pathkey = NIL;
restrictinfo->right_pathkey = NIL;