aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-05-27 00:13:09 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-05-27 00:13:09 +0000
commit7b8a63c3e922b8730e98a20a2c30c5460ddf2306 (patch)
treea66a78e79e9e8efb89622f5206461e469b54fd3c /src/backend
parenta3d9a2421ad3c16c22c82734a1d12be472bf9ba5 (diff)
downloadpostgresql-7b8a63c3e922b8730e98a20a2c30c5460ddf2306.tar.gz
postgresql-7b8a63c3e922b8730e98a20a2c30c5460ddf2306.zip
Alter the xxx_pattern_ops opclasses to use the regular equality operator of
the associated datatype as their equality member. This means that these opclasses can now support plain equality comparisons along with LIKE tests, thus avoiding the need for an extra index in some applications. This optimization was not possible when the pattern opclasses were first introduced, because we didn't insist that text equality meant bitwise equality; but we do now, so there is no semantic difference between regular and pattern equality operators. I removed the name_pattern_ops opclass altogether, since it's really useless: name's regular comparisons are just strcmp() and are unlikely to become something different. Instead teach indxpath.c that btree name_ops can be used for LIKE whether or not the locale is C. This might lead to a useful speedup in LIKE queries on the system catalogs in non-C locales. The ~=~ and ~<>~ operators are gone altogether. (It would have been nice to keep them for backward compatibility's sake, but since the pg_amop structure doesn't allow multiple equality operators per opclass, there's no way.) A not-immediately-obvious incompatibility is that the sort order within bpchar_pattern_ops indexes changes --- it had been identical to plain strcmp, but is now trailing-blank-insensitive. This will impact in-place upgrades, if those ever happen. Per discussions a couple months ago.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/nbtree/nbtcompare.c11
-rw-r--r--src/backend/optimizer/path/indxpath.c8
-rw-r--r--src/backend/utils/adt/name.c61
-rw-r--r--src/backend/utils/adt/varchar.c111
-rw-r--r--src/backend/utils/adt/varlena.c57
5 files changed, 127 insertions, 121 deletions
diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c
index 428d3927c2c..697365e6c26 100644
--- a/src/backend/access/nbtree/nbtcompare.c
+++ b/src/backend/access/nbtree/nbtcompare.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.55 2008/01/01 19:45:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.56 2008/05/27 00:13:08 tgl Exp $
*
* NOTES
*
@@ -237,12 +237,3 @@ btnamecmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN));
}
-
-Datum
-btname_pattern_cmp(PG_FUNCTION_ARGS)
-{
- Name a = PG_GETARG_NAME(0);
- Name b = PG_GETARG_NAME(1);
-
- PG_RETURN_INT32(memcmp(NameStr(*a), NameStr(*b), NAMEDATALEN));
-}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 4fc7c536548..e0bd5480083 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.230 2008/05/16 16:31:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.231 2008/05/27 00:13:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2178,9 +2178,8 @@ match_special_index_operator(Expr *clause, Oid opfamily,
case OID_NAME_ICLIKE_OP:
case OID_NAME_REGEXEQ_OP:
case OID_NAME_ICREGEXEQ_OP:
- isIndexable =
- (opfamily == NAME_PATTERN_BTREE_FAM_OID) ||
- (opfamily == NAME_BTREE_FAM_OID && lc_collate_is_c());
+ /* name uses locale-insensitive sorting */
+ isIndexable = (opfamily == NAME_BTREE_FAM_OID);
break;
case OID_BYTEA_LIKE_OP:
@@ -2700,7 +2699,6 @@ prefix_quals(Node *leftop, Oid opfamily,
break;
case NAME_BTREE_FAM_OID:
- case NAME_PATTERN_BTREE_FAM_OID:
datatype = NAMEOID;
break;
diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c
index 324736ea63e..96f398e5bb2 100644
--- a/src/backend/utils/adt/name.c
+++ b/src/backend/utils/adt/name.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.61 2008/01/01 19:45:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.62 2008/05/27 00:13:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -181,65 +181,6 @@ namege(PG_FUNCTION_ARGS)
}
-/*
- * comparison routines for LIKE indexing support
- */
-
-Datum
-name_pattern_eq(PG_FUNCTION_ARGS)
-{
- Name arg1 = PG_GETARG_NAME(0);
- Name arg2 = PG_GETARG_NAME(1);
-
- PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0);
-}
-
-Datum
-name_pattern_ne(PG_FUNCTION_ARGS)
-{
- Name arg1 = PG_GETARG_NAME(0);
- Name arg2 = PG_GETARG_NAME(1);
-
- PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0);
-}
-
-Datum
-name_pattern_lt(PG_FUNCTION_ARGS)
-{
- Name arg1 = PG_GETARG_NAME(0);
- Name arg2 = PG_GETARG_NAME(1);
-
- PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0);
-}
-
-Datum
-name_pattern_le(PG_FUNCTION_ARGS)
-{
- Name arg1 = PG_GETARG_NAME(0);
- Name arg2 = PG_GETARG_NAME(1);
-
- PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0);
-}
-
-Datum
-name_pattern_gt(PG_FUNCTION_ARGS)
-{
- Name arg1 = PG_GETARG_NAME(0);
- Name arg2 = PG_GETARG_NAME(1);
-
- PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0);
-}
-
-Datum
-name_pattern_ge(PG_FUNCTION_ARGS)
-{
- Name arg1 = PG_GETARG_NAME(0);
- Name arg2 = PG_GETARG_NAME(1);
-
- PG_RETURN_BOOL(memcmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0);
-}
-
-
/* (see char.c for comparison/operation routines) */
int
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index ad48f564c5b..8192a87cfe8 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.128 2008/05/04 16:42:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.129 2008/05/27 00:13:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -886,3 +886,112 @@ hashbpchar(PG_FUNCTION_ARGS)
return result;
}
+
+
+/*
+ * The following operators support character-by-character comparison
+ * of bpchar datums, to allow building indexes suitable for LIKE clauses.
+ * Note that the regular bpchareq/bpcharne comparison operators are assumed
+ * to be compatible with these!
+ */
+
+static int
+internal_bpchar_pattern_compare(BpChar *arg1, BpChar *arg2)
+{
+ int result;
+ int len1,
+ len2;
+
+ len1 = bcTruelen(arg1);
+ len2 = bcTruelen(arg2);
+
+ result = strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
+ if (result != 0)
+ return result;
+ else if (len1 < len2)
+ return -1;
+ else if (len1 > len2)
+ return 1;
+ else
+ return 0;
+}
+
+
+Datum
+bpchar_pattern_lt(PG_FUNCTION_ARGS)
+{
+ BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
+ BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
+ int result;
+
+ result = internal_bpchar_pattern_compare(arg1, arg2);
+
+ PG_FREE_IF_COPY(arg1, 0);
+ PG_FREE_IF_COPY(arg2, 1);
+
+ PG_RETURN_BOOL(result < 0);
+}
+
+
+Datum
+bpchar_pattern_le(PG_FUNCTION_ARGS)
+{
+ BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
+ BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
+ int result;
+
+ result = internal_bpchar_pattern_compare(arg1, arg2);
+
+ PG_FREE_IF_COPY(arg1, 0);
+ PG_FREE_IF_COPY(arg2, 1);
+
+ PG_RETURN_BOOL(result <= 0);
+}
+
+
+Datum
+bpchar_pattern_ge(PG_FUNCTION_ARGS)
+{
+ BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
+ BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
+ int result;
+
+ result = internal_bpchar_pattern_compare(arg1, arg2);
+
+ PG_FREE_IF_COPY(arg1, 0);
+ PG_FREE_IF_COPY(arg2, 1);
+
+ PG_RETURN_BOOL(result >= 0);
+}
+
+
+Datum
+bpchar_pattern_gt(PG_FUNCTION_ARGS)
+{
+ BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
+ BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
+ int result;
+
+ result = internal_bpchar_pattern_compare(arg1, arg2);
+
+ PG_FREE_IF_COPY(arg1, 0);
+ PG_FREE_IF_COPY(arg2, 1);
+
+ PG_RETURN_BOOL(result > 0);
+}
+
+
+Datum
+btbpchar_pattern_cmp(PG_FUNCTION_ARGS)
+{
+ BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
+ BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
+ int result;
+
+ result = internal_bpchar_pattern_compare(arg1, arg2);
+
+ PG_FREE_IF_COPY(arg1, 0);
+ PG_FREE_IF_COPY(arg2, 1);
+
+ PG_RETURN_INT32(result);
+}
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 433049ec022..164ff849560 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.166 2008/05/12 00:00:51 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.167 2008/05/27 00:13:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1309,22 +1309,27 @@ text_smaller(PG_FUNCTION_ARGS)
/*
* The following operators support character-by-character comparison
- * of text data types, to allow building indexes suitable for LIKE
- * clauses.
+ * of text datums, to allow building indexes suitable for LIKE clauses.
+ * Note that the regular texteq/textne comparison operators are assumed
+ * to be compatible with these!
*/
static int
internal_text_pattern_compare(text *arg1, text *arg2)
{
int result;
+ int len1,
+ len2;
+
+ len1 = VARSIZE_ANY_EXHDR(arg1);
+ len2 = VARSIZE_ANY_EXHDR(arg2);
- result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
- Min(VARSIZE_ANY_EXHDR(arg1), VARSIZE_ANY_EXHDR(arg2)));
+ result = strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
if (result != 0)
return result;
- else if (VARSIZE_ANY_EXHDR(arg1) < VARSIZE_ANY_EXHDR(arg2))
+ else if (len1 < len2)
return -1;
- else if (VARSIZE_ANY_EXHDR(arg1) > VARSIZE_ANY_EXHDR(arg2))
+ else if (len1 > len2)
return 1;
else
return 0;
@@ -1364,25 +1369,6 @@ text_pattern_le(PG_FUNCTION_ARGS)
Datum
-text_pattern_eq(PG_FUNCTION_ARGS)
-{
- text *arg1 = PG_GETARG_TEXT_PP(0);
- text *arg2 = PG_GETARG_TEXT_PP(1);
- int result;
-
- if (VARSIZE_ANY_EXHDR(arg1) != VARSIZE_ANY_EXHDR(arg2))
- result = 1;
- else
- result = internal_text_pattern_compare(arg1, arg2);
-
- PG_FREE_IF_COPY(arg1, 0);
- PG_FREE_IF_COPY(arg2, 1);
-
- PG_RETURN_BOOL(result == 0);
-}
-
-
-Datum
text_pattern_ge(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_PP(0);
@@ -1415,25 +1401,6 @@ text_pattern_gt(PG_FUNCTION_ARGS)
Datum
-text_pattern_ne(PG_FUNCTION_ARGS)
-{
- text *arg1 = PG_GETARG_TEXT_PP(0);
- text *arg2 = PG_GETARG_TEXT_PP(1);
- int result;
-
- if (VARSIZE_ANY_EXHDR(arg1) != VARSIZE_ANY_EXHDR(arg2))
- result = 1;
- else
- result = internal_text_pattern_compare(arg1, arg2);
-
- PG_FREE_IF_COPY(arg1, 0);
- PG_FREE_IF_COPY(arg2, 1);
-
- PG_RETURN_BOOL(result != 0);
-}
-
-
-Datum
bttext_pattern_cmp(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_PP(0);