aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/indxpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/indxpath.c')
-rw-r--r--src/backend/optimizer/path/indxpath.c77
1 files changed, 47 insertions, 30 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 908dbc481f2..4fc7c536548 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.229 2008/04/13 20:51:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.230 2008/05/16 16:31:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2364,7 +2364,10 @@ expand_boolean_index_clause(Node *clause,
* expand_indexqual_opclause --- expand a single indexqual condition
* that is an operator clause
*
- * The input is a single RestrictInfo, the output a list of RestrictInfos
+ * The input is a single RestrictInfo, the output a list of RestrictInfos.
+ *
+ * In the base case this is just list_make1(), but we have to be prepared to
+ * expand special cases that were accepted by match_special_index_operator().
*/
static List *
expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
@@ -2379,63 +2382,77 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
Const *prefix = NULL;
Const *rest = NULL;
Pattern_Prefix_Status pstatus;
- List *result;
+ /*
+ * LIKE and regex operators are not members of any btree index opfamily,
+ * but they can be members of opfamilies for more exotic index types such
+ * as GIN. Therefore, we should only do expansion if the operator is
+ * actually not in the opfamily. But checking that requires a syscache
+ * lookup, so it's best to first see if the operator is one we are
+ * interested in.
+ */
switch (expr_op)
{
- /*
- * 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().
- */
case OID_TEXT_LIKE_OP:
case OID_BPCHAR_LIKE_OP:
case OID_NAME_LIKE_OP:
case OID_BYTEA_LIKE_OP:
- pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like,
- &prefix, &rest);
- result = prefix_quals(leftop, opfamily, prefix, pstatus);
+ if (!op_in_opfamily(expr_op, opfamily))
+ {
+ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like,
+ &prefix, &rest);
+ return prefix_quals(leftop, opfamily, prefix, pstatus);
+ }
break;
case OID_TEXT_ICLIKE_OP:
case OID_BPCHAR_ICLIKE_OP:
case OID_NAME_ICLIKE_OP:
- /* 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, opfamily, prefix, pstatus);
+ if (!op_in_opfamily(expr_op, opfamily))
+ {
+ /* the right-hand const is type text for all of these */
+ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
+ &prefix, &rest);
+ return prefix_quals(leftop, opfamily, prefix, pstatus);
+ }
break;
case OID_TEXT_REGEXEQ_OP:
case OID_BPCHAR_REGEXEQ_OP:
case OID_NAME_REGEXEQ_OP:
- /* 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, opfamily, prefix, pstatus);
+ if (!op_in_opfamily(expr_op, opfamily))
+ {
+ /* the right-hand const is type text for all of these */
+ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex,
+ &prefix, &rest);
+ return prefix_quals(leftop, opfamily, prefix, pstatus);
+ }
break;
case OID_TEXT_ICREGEXEQ_OP:
case OID_BPCHAR_ICREGEXEQ_OP:
case OID_NAME_ICREGEXEQ_OP:
- /* 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, opfamily, prefix, pstatus);
+ if (!op_in_opfamily(expr_op, opfamily))
+ {
+ /* the right-hand const is type text for all of these */
+ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
+ &prefix, &rest);
+ return prefix_quals(leftop, opfamily, prefix, pstatus);
+ }
break;
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- result = network_prefix_quals(leftop, expr_op, opfamily,
- patt->constvalue);
- break;
-
- default:
- result = list_make1(rinfo);
+ if (!op_in_opfamily(expr_op, opfamily))
+ {
+ return network_prefix_quals(leftop, expr_op, opfamily,
+ patt->constvalue);
+ }
break;
}
- return result;
+ /* Default case: just make a list of the unmodified indexqual */
+ return list_make1(rinfo);
}
/*