Indexing support for pattern matching operations via separate operator

class when lc_collate is not C.
This commit is contained in:
Peter Eisentraut 2003-05-15 15:50:21 +00:00
parent 2a2f6cfa39
commit 2c0556068f
20 changed files with 489 additions and 208 deletions

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v 2.35 2003/04/15 13:26:54 petere Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/charset.sgml,v 2.36 2003/05/15 15:50:18 petere Exp $ -->
<chapter id="charset">
<title>Localization</>
@ -213,23 +213,13 @@ initdb --locale=sv_SE
The <function>to_char</> family of functions
</para>
</listitem>
<listitem>
<para>
The <literal>LIKE</> and <literal>~</> operators for pattern
matching
</para>
</listitem>
</itemizedlist>
</para>
<para>
The only severe drawback of using the locale support in
<productname>PostgreSQL</> is its speed. So use locales only if you
actually need it. It should be noted in particular that selecting
a non-C locale disables index optimizations for <literal>LIKE</> and
<literal>~</> operators, which can make a huge difference in the
speed of searches that use those operators.
<productname>PostgreSQL</> is its speed. So use locales only if
you actually need them.
</para>
</sect2>

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.40 2003/03/25 16:15:36 petere Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/indices.sgml,v 1.41 2003/05/15 15:50:18 petere Exp $ -->
<chapter id="indexes">
<title id="indexes-title">Indexes</title>
@ -132,6 +132,19 @@ CREATE INDEX test1_id_index ON test1 (id);
</simplelist>
</para>
<para>
The optimizer can also use a B-tree index for queries involving the
pattern matching operators <literal>LIKE</>,
<literal>ILIKE</literal>, <literal>~</literal>, and
<literal>~*</literal>, <emphasis>if</emphasis> the pattern is
anchored to the beginning of the string, e.g., <literal>col LIKE
'foo%'</literal> or <literal>col ~ '^foo'</literal>, but not
<literal>col LIKE '%bar'</literal>. However, if your server does
not use the C locale you will need to create the index with a
special operator class. See <xref linkend="indexes-opclass">
below.
</para>
<para>
<indexterm>
<primary>indexes</primary>
@ -405,6 +418,36 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
<literal>bigbox_ops</literal>.
</para>
</listitem>
<listitem>
<para>
The operator classes <literal>text_pattern_ops</literal>,
<literal>varchar_pattern_ops</literal>,
<literal>bpchar_pattern_ops</literal>, and
<literal>name_pattern_ops</literal> support B-tree indexes on
the types <type>text</type>, <type>varchar</type>,
<type>char</type>, and <type>name</type>, respectively. The
difference to the ordinary operator classes is that the values
are compared strictly character by character rather than
according to the locale-specific collation rules. This makes
these operator classes suitable for use by queries involving
pattern matching expressions (<literal>LIKE</literal> or POSIX
regular expressions) if the server does not use the standard
<quote>C</quote> locale. As an example, to index a
<type>varchar</type> column like this:
<programlisting>
CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
</programlisting>
If you do use the C locale, you should instead create an index
with the default operator class. Also note that you should
create an index with the default operator class if you want
queries involving ordinary comparisons to use an index. Such
queries cannot use the
<literal><replaceable>xxx</replaceable>_pattern_ops</literal>
operator classes. It is possible, however, to create multiple
indexes on the same column with different operator classes.
</para>
</listitem>
</itemizedlist>
</para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.187 2003/05/14 03:25:59 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.188 2003/05/15 15:50:18 petere Exp $
-->
<appendix id="release">
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
Pattern matching operations can use indexes regardless of locale
New frontend/backend protocol supports many long-requested features
SET AUTOCOMMIT TO OFF is no longer supported
Reimplementation of NUMERIC datatype for more speed

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.179 2003/05/14 03:26:00 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.180 2003/05/15 15:50:18 petere Exp $
-->
<Chapter Id="runtime">
@ -133,26 +133,13 @@ postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
</para>
<para>
<command>initdb</command> also initializes the default locale<indexterm><primary>locale</></> for
the database cluster. Normally, it will just take the locale
settings in the environment and apply them to the initialized
database. It is possible to specify a different locale for the
database; more information about that can be found in <xref
linkend="locale">. One surprise you might encounter while running
<command>initdb</command> is a notice similar to this:
<screen>
The database cluster will be initialized with locale de_DE.
This locale setting will prevent the use of indexes for pattern matching
operations. If that is a concern, rerun initdb with the collation order
set to "C". For more information see the documentation.
</screen>
This is intended to warn you that the currently selected locale
will cause indexes to be sorted in an order that prevents them from
being used for <literal>LIKE</> and regular-expression searches. If you need
good performance in such searches, you should set your current
locale to <literal>C</> and re-run <command>initdb</command>, e.g.,
by running <literal>initdb --lc-collate=C</literal>. The sort
order used within a particular database cluster is set by
<command>initdb</command> also initializes the default
locale<indexterm><primary>locale</></> for the database cluster.
Normally, it will just take the locale settings in the environment
and apply them to the initialized database. It is possible to
specify a different locale for the database; more information about
that can be found in <xref linkend="locale">. The sort order used
within a particular database cluster is set by
<command>initdb</command> and cannot be changed later, short of
dumping all data, rerunning <command>initdb</command>, and
reloading the data. So it's important to make this choice correctly

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.44 2002/06/20 20:29:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.45 2003/05/15 15:50:18 petere Exp $
*
* NOTES
*
@ -149,3 +149,12 @@ 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));
}

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.137 2003/05/13 04:38:58 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.138 2003/05/15 15:50:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -1797,14 +1797,13 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_VARCHAR_LIKE_OP:
case OID_NAME_LIKE_OP:
/* the right-hand const is type text for all of these */
if (locale_is_like_safe())
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like,
&prefix, &rest) != Pattern_Prefix_None;
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like,
&prefix, &rest) != Pattern_Prefix_None;
break;
case OID_BYTEA_LIKE_OP:
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like,
&prefix, &rest) != Pattern_Prefix_None;
&prefix, &rest) != Pattern_Prefix_None;
break;
case OID_TEXT_ICLIKE_OP:
@ -1812,9 +1811,8 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_VARCHAR_ICLIKE_OP:
case OID_NAME_ICLIKE_OP:
/* the right-hand const is type text for all of these */
if (locale_is_like_safe())
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
&prefix, &rest) != Pattern_Prefix_None;
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
&prefix, &rest) != Pattern_Prefix_None;
break;
case OID_TEXT_REGEXEQ_OP:
@ -1822,9 +1820,8 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_VARCHAR_REGEXEQ_OP:
case OID_NAME_REGEXEQ_OP:
/* the right-hand const is type text for all of these */
if (locale_is_like_safe())
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Regex,
&prefix, &rest) != Pattern_Prefix_None;
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Regex,
&prefix, &rest) != Pattern_Prefix_None;
break;
case OID_TEXT_ICREGEXEQ_OP:
@ -1832,9 +1829,8 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_VARCHAR_ICREGEXEQ_OP:
case OID_NAME_ICREGEXEQ_OP:
/* the right-hand const is type text for all of these */
if (locale_is_like_safe())
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
&prefix, &rest) != Pattern_Prefix_None;
isIndexable = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
&prefix, &rest) != Pattern_Prefix_None;
break;
case OID_INET_SUB_OP:
@ -1867,42 +1863,53 @@ match_special_index_operator(Expr *clause, Oid opclass,
case OID_TEXT_ICLIKE_OP:
case OID_TEXT_REGEXEQ_OP:
case OID_TEXT_ICREGEXEQ_OP:
if (!op_in_opclass(find_operator(">=", TEXTOID), opclass) ||
!op_in_opclass(find_operator("<", TEXTOID), opclass))
isIndexable = false;
if (lc_collate_is_c())
isIndexable = (op_in_opclass(find_operator(">=", TEXTOID), opclass)
&& op_in_opclass(find_operator("<", TEXTOID), opclass));
else
isIndexable = (op_in_opclass(find_operator("~>=~", TEXTOID), opclass)
&& op_in_opclass(find_operator("~<~", TEXTOID), opclass));
break;
case OID_BYTEA_LIKE_OP:
if (!op_in_opclass(find_operator(">=", BYTEAOID), opclass) ||
!op_in_opclass(find_operator("<", BYTEAOID), opclass))
isIndexable = false;
isIndexable = (op_in_opclass(find_operator(">=", BYTEAOID), opclass)
&& op_in_opclass(find_operator("<", BYTEAOID), opclass));
break;
case OID_BPCHAR_LIKE_OP:
case OID_BPCHAR_ICLIKE_OP:
case OID_BPCHAR_REGEXEQ_OP:
case OID_BPCHAR_ICREGEXEQ_OP:
if (!op_in_opclass(find_operator(">=", BPCHAROID), opclass) ||
!op_in_opclass(find_operator("<", BPCHAROID), opclass))
isIndexable = false;
if (lc_collate_is_c())
isIndexable = (op_in_opclass(find_operator(">=", BPCHAROID), opclass)
&& op_in_opclass(find_operator("<", BPCHAROID), opclass));
else
isIndexable = (op_in_opclass(find_operator("~>=~", BPCHAROID), opclass)
&& op_in_opclass(find_operator("~<~", BPCHAROID), opclass));
break;
case OID_VARCHAR_LIKE_OP:
case OID_VARCHAR_ICLIKE_OP:
case OID_VARCHAR_REGEXEQ_OP:
case OID_VARCHAR_ICREGEXEQ_OP:
if (!op_in_opclass(find_operator(">=", VARCHAROID), opclass) ||
!op_in_opclass(find_operator("<", VARCHAROID), opclass))
isIndexable = false;
if (lc_collate_is_c())
isIndexable = (op_in_opclass(find_operator(">=", VARCHAROID), opclass)
&& op_in_opclass(find_operator("<", VARCHAROID), opclass));
else
isIndexable = (op_in_opclass(find_operator("~>=~", VARCHAROID), opclass)
&& op_in_opclass(find_operator("~<~", VARCHAROID), opclass));
break;
case OID_NAME_LIKE_OP:
case OID_NAME_ICLIKE_OP:
case OID_NAME_REGEXEQ_OP:
case OID_NAME_ICREGEXEQ_OP:
if (!op_in_opclass(find_operator(">=", NAMEOID), opclass) ||
!op_in_opclass(find_operator("<", NAMEOID), opclass))
isIndexable = false;
if (lc_collate_is_c())
isIndexable = (op_in_opclass(find_operator(">=", NAMEOID), opclass)
&& op_in_opclass(find_operator("<", NAMEOID), opclass));
else
isIndexable = (op_in_opclass(find_operator("~>=~", NAMEOID), opclass)
&& op_in_opclass(find_operator("~<~", NAMEOID), opclass));
break;
case OID_INET_SUB_OP:
@ -2039,6 +2046,7 @@ prefix_quals(Node *leftop, Oid expr_op,
List *result;
Oid datatype;
Oid oproid;
const char *oprname;
char *prefix;
Const *con;
Expr *expr;
@ -2098,9 +2106,10 @@ prefix_quals(Node *leftop, Oid expr_op,
*/
if (pstatus == Pattern_Prefix_Exact)
{
oproid = find_operator("=", datatype);
oprname = (datatype == BYTEAOID || lc_collate_is_c() ? "=" : "~=~");
oproid = find_operator(oprname, datatype);
if (oproid == InvalidOid)
elog(ERROR, "prefix_quals: no = operator for type %u", datatype);
elog(ERROR, "prefix_quals: no operator %s for type %u", oprname, datatype);
con = string_to_const(prefix, datatype);
expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftop, (Expr *) con);
@ -2113,9 +2122,10 @@ prefix_quals(Node *leftop, Oid expr_op,
*
* We can always say "x >= prefix".
*/
oproid = find_operator(">=", datatype);
oprname = (datatype == BYTEAOID || lc_collate_is_c() ? ">=" : "~>=~");
oproid = find_operator(oprname, datatype);
if (oproid == InvalidOid)
elog(ERROR, "prefix_quals: no >= operator for type %u", datatype);
elog(ERROR, "prefix_quals: no operator %s for type %u", oprname, datatype);
con = string_to_const(prefix, datatype);
expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftop, (Expr *) con);
@ -2129,9 +2139,10 @@ prefix_quals(Node *leftop, Oid expr_op,
greaterstr = make_greater_string(con);
if (greaterstr)
{
oproid = find_operator("<", datatype);
oprname = (datatype == BYTEAOID || lc_collate_is_c() ? "<" : "~<~");
oproid = find_operator(oprname, datatype);
if (oproid == InvalidOid)
elog(ERROR, "prefix_quals: no < operator for type %u", datatype);
elog(ERROR, "prefix_quals: no operator %s for type %u", oprname, datatype);
expr = make_opclause(oproid, BOOLOID, false,
(Expr *) leftop, (Expr *) greaterstr);
result = lappend(result, expr);

View File

@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.45 2003/05/09 21:19:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.46 2003/05/15 15:50:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -182,6 +182,65 @@ 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

View File

@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.136 2003/04/16 04:37:58 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.137 2003/05/15 15:50:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -180,8 +180,6 @@ static void get_join_vars(List *args, Var **var1, Var **var2);
static Selectivity prefix_selectivity(Query *root, Var *var, Oid vartype,
Const *prefix);
static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype);
static bool string_lessthan(const char *str1, const char *str2,
Oid datatype);
static Oid find_operator(const char *opname, Oid datatype);
static Datum string_to_datum(const char *str, Oid datatype);
static Const *string_to_const(const char *str, Oid datatype);
@ -3619,51 +3617,21 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
/*
* We want to test whether the database's LC_COLLATE setting is safe for
* LIKE/regexp index optimization.
* Try to generate a string greater than the given string or any
* string it is a prefix of. If successful, return a palloc'd string;
* else return NULL.
*
* The key requirement here is that given a prefix string, say "foo",
* we must be able to generate another string "fop" that is greater
* than all strings "foobar" starting with "foo". Unfortunately, a
* non-C locale may have arbitrary collation rules in which "fop" >
* "foo" is not sufficient to ensure "fop" > "foobar". Until we can
* come up with a more bulletproof way of generating the upper-bound
* string, the optimization is disabled in all non-C locales.
* than all strings "foobar" starting with "foo".
*
* (In theory, locales other than C may be LIKE-safe so this function
* could be different from lc_collate_is_c(), but in a different
* theory, non-C locales are completely unpredictable so it's unlikely
* to happen.)
* If we max out the righthand byte, truncate off the last character
* and start incrementing the next. For example, if "z" were the last
* character in the sort order, then we could produce "foo" as a
* string greater than "fonz".
*
* Be sure to maintain the correspondence with the code in initdb.
*/
bool
locale_is_like_safe(void)
{
return lc_collate_is_c();
}
/*
* Try to generate a string greater than the given string or any string it is
* a prefix of. If successful, return a palloc'd string; else return NULL.
*
* To work correctly in non-ASCII locales with weird collation orders,
* we cannot simply increment "foo" to "fop" --- we have to check whether
* we actually produced a string greater than the given one. If not,
* increment the righthand byte again and repeat. If we max out the righthand
* byte, truncate off the last character and start incrementing the next.
* For example, if "z" were the last character in the sort order, then we
* could produce "foo" as a string greater than "fonz".
*
* This could be rather slow in the worst case, but in most cases we won't
* have to try more than one or two strings before succeeding.
*
* XXX this is actually not sufficient, since it only copes with the case
* where individual characters collate in an order different from their
* numeric code assignments. It does not handle cases where there are
* cross-character effects, such as specially sorted digraphs, multiple
* sort passes, etc. For now, we just shut down the whole thing in locales
* that do such things :-(
* This could be rather slow in the worst case, but in most cases we
* won't have to try more than one or two strings before succeeding.
*/
Const *
make_greater_string(const Const *str_const)
@ -3699,18 +3667,16 @@ make_greater_string(const Const *str_const)
/*
* Try to generate a larger string by incrementing the last byte.
*/
while (*lastchar < (unsigned char) 255)
if (*lastchar < (unsigned char) 255)
{
(*lastchar)++;
if (string_lessthan(str, workstr, datatype))
{
/* Success! */
Const *workstr_const = string_to_const(workstr, datatype);
Const *workstr_const;
pfree(str);
pfree(workstr);
return workstr_const;
}
(*lastchar)++;
workstr_const = string_to_const(workstr, datatype);
pfree(str);
pfree(workstr);
return workstr_const;
}
/* restore last byte so we don't confuse pg_mbcliplen */
@ -3736,57 +3702,6 @@ make_greater_string(const Const *str_const)
return (Const *) NULL;
}
/*
* Test whether two strings are "<" according to the rules of the given
* datatype. We do this the hard way, ie, actually calling the type's
* "<" operator function, to ensure we get the right result...
*/
static bool
string_lessthan(const char *str1, const char *str2, Oid datatype)
{
Datum datum1 = string_to_datum(str1, datatype);
Datum datum2 = string_to_datum(str2, datatype);
bool result;
switch (datatype)
{
case TEXTOID:
result = DatumGetBool(DirectFunctionCall2(text_lt,
datum1, datum2));
break;
case BPCHAROID:
result = DatumGetBool(DirectFunctionCall2(bpcharlt,
datum1, datum2));
break;
case VARCHAROID:
result = DatumGetBool(DirectFunctionCall2(varcharlt,
datum1, datum2));
break;
case NAMEOID:
result = DatumGetBool(DirectFunctionCall2(namelt,
datum1, datum2));
break;
case BYTEAOID:
result = DatumGetBool(DirectFunctionCall2(bytealt,
datum1, datum2));
break;
default:
elog(ERROR, "string_lessthan: unexpected datatype %u", datatype);
result = false;
break;
}
pfree(DatumGetPointer(datum1));
pfree(DatumGetPointer(datum2));
return result;
}
/* See if there is a binary op of the given name for the given datatype */
/* NB: we assume that only built-in system operators are searched for */
static Oid

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.97 2003/05/09 15:44:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.98 2003/05/15 15:50:19 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -1050,6 +1050,149 @@ text_smaller(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
/*
* The following operators support character-by-character comparison
* of text data types, to allow building indexes suitable for LIKE
* clauses.
*/
static int
internal_text_pattern_compare(text *arg1, text *arg2)
{
int result;
result = memcmp(VARDATA(arg1), VARDATA(arg2),
Min(VARSIZE(arg1), VARSIZE(arg2)) - VARHDRSZ);
if (result != 0)
return result;
else if (VARSIZE(arg1) < VARSIZE(arg2))
return -1;
else if (VARSIZE(arg1) > VARSIZE(arg2))
return 1;
else
return 0;
}
Datum
text_pattern_lt(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
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_le(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
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_eq(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
if (VARSIZE(arg1) != VARSIZE(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_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
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_gt(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
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_ne(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
if (VARSIZE(arg1) != VARSIZE(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_P(0);
text *arg2 = PG_GETARG_TEXT_P(1);
int result;
result = internal_text_pattern_compare(arg1, arg2);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_INT32(result);
}
/*-------------------------------------------------------------
* byteaoctetlen
*

View File

@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.188 2003/04/04 03:03:53 tgl Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.189 2003/05/15 15:50:19 petere Exp $
#
#-------------------------------------------------------------------------
@ -478,13 +478,6 @@ else
echo " COLLATE: `pg_getlocale COLLATE`${TAB}CTYPE: `pg_getlocale CTYPE`${TAB}MESSAGES: `pg_getlocale MESSAGES`"
echo " MONETARY: `pg_getlocale MONETARY`${TAB}NUMERIC: `pg_getlocale NUMERIC`${TAB}TIME: `pg_getlocale TIME`"
fi
# (Be sure to maintain the correspondence with locale_is_like_safe() in selfuncs.c.)
if test x`pg_getlocale COLLATE` != xC && test x`pg_getlocale COLLATE` != xPOSIX; then
echo "This locale setting will prevent the use of indexes for pattern matching"
echo "operations. If that is a concern, rerun $CMDNAME with the collation order"
echo "set to \"C\". For more information see the documentation."
fi
echo

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.193 2003/05/13 18:03:07 tgl Exp $
* $Id: catversion.h,v 1.194 2003/05/15 15:50:19 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200305131
#define CATALOG_VERSION_NO 200305151
#endif

View File

@ -16,7 +16,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_amop.h,v 1.47 2003/03/10 22:28:19 tgl Exp $
* $Id: pg_amop.h,v 1.48 2003/05/15 15:50:19 petere Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -378,6 +378,46 @@ DATA(insert ( 2002 3 f 1804 ));
DATA(insert ( 2002 4 f 1809 ));
DATA(insert ( 2002 5 f 1807 ));
/*
* btree text pattern
*/
DATA(insert ( 2095 1 f 2314 ));
DATA(insert ( 2095 2 f 2315 ));
DATA(insert ( 2095 3 f 2316 ));
DATA(insert ( 2095 4 f 2317 ));
DATA(insert ( 2095 5 f 2318 ));
/*
* btree varchar pattern
*/
DATA(insert ( 2096 1 f 2320 ));
DATA(insert ( 2096 2 f 2321 ));
DATA(insert ( 2096 3 f 2322 ));
DATA(insert ( 2096 4 f 2323 ));
DATA(insert ( 2096 5 f 2324 ));
/*
* btree bpchar pattern
*/
DATA(insert ( 2097 1 f 2326 ));
DATA(insert ( 2097 2 f 2327 ));
DATA(insert ( 2097 3 f 2328 ));
DATA(insert ( 2097 4 f 2329 ));
DATA(insert ( 2097 5 f 2330 ));
/*
* btree name pattern
*/
DATA(insert ( 2098 1 f 2332 ));
DATA(insert ( 2098 2 f 2333 ));
DATA(insert ( 2098 3 f 2334 ));
DATA(insert ( 2098 4 f 2335 ));
DATA(insert ( 2098 5 f 2336 ));
/*
* hash index _ops

View File

@ -14,7 +14,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_amproc.h,v 1.35 2002/06/20 20:29:44 momjian Exp $
* $Id: pg_amproc.h,v 1.36 2003/05/15 15:50:19 petere Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -105,6 +105,10 @@ DATA(insert ( 2000 1 1358 ));
DATA(insert ( 2002 1 1672 ));
DATA(insert ( 2003 1 1079 ));
DATA(insert ( 2039 1 1314 ));
DATA(insert ( 2095 1 2166 ));
DATA(insert ( 2096 1 2173 ));
DATA(insert ( 2097 1 2180 ));
DATA(insert ( 2098 1 2187 ));
/* hash */

View File

@ -26,7 +26,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_opclass.h,v 1.47 2003/03/10 22:28:19 tgl Exp $
* $Id: pg_opclass.h,v 1.48 2003/05/15 15:50:19 petere Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -140,5 +140,9 @@ DATA(insert OID = 2003 ( 403 varchar_ops PGNSP PGUID 1043 t 0 ));
DATA(insert OID = 2004 ( 405 varchar_ops PGNSP PGUID 1043 t 0 ));
DATA(insert OID = 2039 ( 403 timestamp_ops PGNSP PGUID 1114 t 0 ));
DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID 1114 t 0 ));
DATA(insert OID = 2095 ( 403 text_pattern_ops PGNSP PGUID 25 f 0 ));
DATA(insert OID = 2096 ( 403 varchar_pattern_ops PGNSP PGUID 1043 f 0 ));
DATA(insert OID = 2097 ( 403 bpchar_pattern_ops PGNSP PGUID 1042 f 0 ));
DATA(insert OID = 2098 ( 403 name_pattern_ops PGNSP PGUID 19 f 0 ));
#endif /* PG_OPCLASS_H */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_operator.h,v 1.112 2003/04/08 23:20:03 tgl Exp $
* $Id: pg_operator.h,v 1.113 2003/05/15 15:50:19 petere Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -814,6 +814,37 @@ DATA(insert OID = 2066 ( "+" PGNSP PGUID b f 1114 1186 1114 0 0 0 0 0 0 tim
DATA(insert OID = 2067 ( "-" PGNSP PGUID b f 1114 1114 1186 0 0 0 0 0 0 timestamp_mi - - ));
DATA(insert OID = 2068 ( "-" PGNSP PGUID b f 1114 1186 1114 0 0 0 0 0 0 timestamp_mi_span - - ));
/* character-by-character (not collation order) comparison operators for character types */
DATA(insert OID = 2314 ( "~<~" PGNSP PGUID b f 25 25 16 2318 2317 0 0 0 0 text_pattern_lt scalarltsel scalarltjoinsel ));
DATA(insert OID = 2315 ( "~<=~" PGNSP PGUID b f 25 25 16 2317 2318 0 0 0 0 text_pattern_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 2316 ( "~=~" PGNSP PGUID b t 25 25 16 2316 2319 2314 2314 2314 2318 text_pattern_eq eqsel eqjoinsel ));
DATA(insert OID = 2317 ( "~>=~" PGNSP PGUID b f 25 25 16 2315 2314 0 0 0 0 text_pattern_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 2318 ( "~>~" PGNSP PGUID b f 25 25 16 2314 2315 0 0 0 0 text_pattern_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 2319 ( "~<>~" PGNSP PGUID b f 25 25 16 2319 2316 0 0 0 0 text_pattern_ne neqsel neqjoinsel ));
DATA(insert OID = 2320 ( "~<~" PGNSP PGUID b f 1043 1043 16 2324 2323 0 0 0 0 varchar_pattern_lt scalarltsel scalarltjoinsel ));
DATA(insert OID = 2321 ( "~<=~" PGNSP PGUID b f 1043 1043 16 2323 2324 0 0 0 0 varchar_pattern_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 2322 ( "~=~" PGNSP PGUID b t 1043 1043 16 2322 2325 2320 2320 2320 2324 varchar_pattern_eq eqsel eqjoinsel ));
DATA(insert OID = 2323 ( "~>=~" PGNSP PGUID b f 1043 1043 16 2321 2320 0 0 0 0 varchar_pattern_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 2324 ( "~>~" PGNSP PGUID b f 1043 1043 16 2320 2321 0 0 0 0 varchar_pattern_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 2325 ( "~<>~" PGNSP PGUID b f 1043 1043 16 2325 2322 0 0 0 0 varchar_pattern_ne neqsel neqjoinsel ));
DATA(insert OID = 2326 ( "~<~" PGNSP PGUID b f 1042 1042 16 2330 2329 0 0 0 0 bpchar_pattern_lt scalarltsel scalarltjoinsel ));
DATA(insert OID = 2327 ( "~<=~" PGNSP PGUID b f 1042 1042 16 2329 2330 0 0 0 0 bpchar_pattern_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 2328 ( "~=~" PGNSP PGUID b t 1042 1042 16 2328 2331 2326 2326 2326 2330 bpchar_pattern_eq eqsel eqjoinsel ));
DATA(insert OID = 2329 ( "~>=~" PGNSP PGUID b f 1042 1042 16 2327 2326 0 0 0 0 bpchar_pattern_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 2330 ( "~>~" PGNSP PGUID b f 1042 1042 16 2326 2327 0 0 0 0 bpchar_pattern_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 2331 ( "~<>~" PGNSP PGUID b f 1042 1042 16 2331 2328 0 0 0 0 bpchar_pattern_ne neqsel neqjoinsel ));
DATA(insert OID = 2332 ( "~<~" PGNSP PGUID b f 19 19 16 2336 2335 0 0 0 0 name_pattern_lt scalarltsel scalarltjoinsel ));
DATA(insert OID = 2333 ( "~<=~" PGNSP PGUID b f 19 19 16 2335 2336 0 0 0 0 name_pattern_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 2334 ( "~=~" PGNSP PGUID b t 19 19 16 2334 2337 2332 2332 2332 2336 name_pattern_eq eqsel eqjoinsel ));
DATA(insert OID = 2335 ( "~>=~" PGNSP PGUID b f 19 19 16 2333 2332 0 0 0 0 name_pattern_ge scalargtsel scalargtjoinsel ));
DATA(insert OID = 2336 ( "~>~" PGNSP PGUID b f 19 19 16 2332 2333 0 0 0 0 name_pattern_gt scalargtsel scalargtjoinsel ));
DATA(insert OID = 2337 ( "~<>~" PGNSP PGUID b f 19 19 16 2337 2334 0 0 0 0 name_pattern_ne neqsel neqjoinsel ));
/*
* function prototypes

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.299 2003/05/13 18:03:07 tgl Exp $
* $Id: pg_proc.h,v 1.300 2003/05/15 15:50:19 petere Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -3024,6 +3024,39 @@ DATA(insert OID = 2157 ( stddev PGNSP PGUID 12 t f f f i 1 701 "700" aggrega
DATA(insert OID = 2158 ( stddev PGNSP PGUID 12 t f f f i 1 701 "701" aggregate_dummy - _null_ ));
DATA(insert OID = 2159 ( stddev PGNSP PGUID 12 t f f f i 1 1700 "1700" aggregate_dummy - _null_ ));
DATA(insert OID = 2160 ( text_pattern_lt PGNSP PGUID 12 f f t f i 2 16 "25 25" text_pattern_lt - _null_ ));
DATA(insert OID = 2161 ( text_pattern_le PGNSP PGUID 12 f f t f i 2 16 "25 25" text_pattern_le - _null_ ));
DATA(insert OID = 2162 ( text_pattern_eq PGNSP PGUID 12 f f t f i 2 16 "25 25" text_pattern_eq - _null_ ));
DATA(insert OID = 2163 ( text_pattern_ge PGNSP PGUID 12 f f t f i 2 16 "25 25" text_pattern_ge - _null_ ));
DATA(insert OID = 2164 ( text_pattern_gt PGNSP PGUID 12 f f t f i 2 16 "25 25" text_pattern_gt - _null_ ));
DATA(insert OID = 2165 ( text_pattern_ne PGNSP PGUID 12 f f t f i 2 16 "25 25" text_pattern_ne - _null_ ));
DATA(insert OID = 2166 ( bttext_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "25 25" bttext_pattern_cmp - _null_ ));
/* We use the same procedures here as above since the types are binary compatible. */
DATA(insert OID = 2167 ( varchar_pattern_lt PGNSP PGUID 12 f f t f i 2 16 "1043 1043" text_pattern_lt - _null_ ));
DATA(insert OID = 2168 ( varchar_pattern_le PGNSP PGUID 12 f f t f i 2 16 "1043 1043" text_pattern_le - _null_ ));
DATA(insert OID = 2169 ( varchar_pattern_eq PGNSP PGUID 12 f f t f i 2 16 "1043 1043" text_pattern_eq - _null_ ));
DATA(insert OID = 2170 ( varchar_pattern_ge PGNSP PGUID 12 f f t f i 2 16 "1043 1043" text_pattern_ge - _null_ ));
DATA(insert OID = 2171 ( varchar_pattern_gt PGNSP PGUID 12 f f t f i 2 16 "1043 1043" text_pattern_gt - _null_ ));
DATA(insert OID = 2172 ( varchar_pattern_ne PGNSP PGUID 12 f f t f i 2 16 "1043 1043" text_pattern_ne - _null_ ));
DATA(insert OID = 2173 ( btvarchar_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "1043 1043" bttext_pattern_cmp - _null_ ));
DATA(insert OID = 2174 ( bpchar_pattern_lt PGNSP PGUID 12 f f t f i 2 16 "1042 1042" text_pattern_lt - _null_ ));
DATA(insert OID = 2175 ( bpchar_pattern_le PGNSP PGUID 12 f f t f i 2 16 "1042 1042" text_pattern_le - _null_ ));
DATA(insert OID = 2176 ( bpchar_pattern_eq PGNSP PGUID 12 f f t f i 2 16 "1042 1042" text_pattern_eq - _null_ ));
DATA(insert OID = 2177 ( bpchar_pattern_ge PGNSP PGUID 12 f f t f i 2 16 "1042 1042" text_pattern_ge - _null_ ));
DATA(insert OID = 2178 ( bpchar_pattern_gt PGNSP PGUID 12 f f t f i 2 16 "1042 1042" text_pattern_gt - _null_ ));
DATA(insert OID = 2179 ( bpchar_pattern_ne PGNSP PGUID 12 f f t f i 2 16 "1042 1042" text_pattern_ne - _null_ ));
DATA(insert OID = 2180 ( btbpchar_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "1042 1042" bttext_pattern_cmp - _null_ ));
DATA(insert OID = 2181 ( name_pattern_lt PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_lt - _null_ ));
DATA(insert OID = 2182 ( name_pattern_le PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_le - _null_ ));
DATA(insert OID = 2183 ( name_pattern_eq PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_eq - _null_ ));
DATA(insert OID = 2184 ( name_pattern_ge PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_ge - _null_ ));
DATA(insert OID = 2185 ( name_pattern_gt PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_gt - _null_ ));
DATA(insert OID = 2186 ( name_pattern_ne PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_ne - _null_ ));
DATA(insert OID = 2187 ( btname_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "19 19" btname_pattern_cmp - _null_ ));
DATA(insert OID = 2212 ( regprocedurein PGNSP PGUID 12 f f t f s 1 2202 "2275" regprocedurein - _null_ ));
DESCR("I/O");

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.216 2003/05/13 18:03:08 tgl Exp $
* $Id: builtins.h,v 1.217 2003/05/15 15:50:20 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -190,6 +190,12 @@ extern Datum namelt(PG_FUNCTION_ARGS);
extern Datum namele(PG_FUNCTION_ARGS);
extern Datum namegt(PG_FUNCTION_ARGS);
extern Datum namege(PG_FUNCTION_ARGS);
extern Datum name_pattern_eq(PG_FUNCTION_ARGS);
extern Datum name_pattern_ne(PG_FUNCTION_ARGS);
extern Datum name_pattern_lt(PG_FUNCTION_ARGS);
extern Datum name_pattern_le(PG_FUNCTION_ARGS);
extern Datum name_pattern_gt(PG_FUNCTION_ARGS);
extern Datum name_pattern_ge(PG_FUNCTION_ARGS);
extern int namecpy(Name n1, Name n2);
extern int namestrcpy(Name name, const char *str);
extern int namestrcmp(Name name, const char *str);
@ -219,6 +225,8 @@ extern Datum btabstimecmp(PG_FUNCTION_ARGS);
extern Datum btcharcmp(PG_FUNCTION_ARGS);
extern Datum btnamecmp(PG_FUNCTION_ARGS);
extern Datum bttextcmp(PG_FUNCTION_ARGS);
extern Datum btname_pattern_cmp(PG_FUNCTION_ARGS);
extern Datum bttext_pattern_cmp(PG_FUNCTION_ARGS);
/* float.c */
extern int extra_float_digits;
@ -512,6 +520,12 @@ extern Datum text_gt(PG_FUNCTION_ARGS);
extern Datum text_ge(PG_FUNCTION_ARGS);
extern Datum text_larger(PG_FUNCTION_ARGS);
extern Datum text_smaller(PG_FUNCTION_ARGS);
extern Datum text_pattern_eq(PG_FUNCTION_ARGS);
extern Datum text_pattern_ne(PG_FUNCTION_ARGS);
extern Datum text_pattern_lt(PG_FUNCTION_ARGS);
extern Datum text_pattern_le(PG_FUNCTION_ARGS);
extern Datum text_pattern_gt(PG_FUNCTION_ARGS);
extern Datum text_pattern_ge(PG_FUNCTION_ARGS);
extern Datum textlen(PG_FUNCTION_ARGS);
extern Datum textoctetlen(PG_FUNCTION_ARGS);
extern Datum textpos(PG_FUNCTION_ARGS);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: selfuncs.h,v 1.12 2003/01/28 22:13:41 tgl Exp $
* $Id: selfuncs.h,v 1.13 2003/05/15 15:50:20 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -37,7 +37,6 @@ extern Pattern_Prefix_Status pattern_fixed_prefix(Const *patt,
Pattern_Type ptype,
Const **prefix,
Const **rest);
extern bool locale_is_like_safe(void);
extern Const *make_greater_string(const Const *str_const);
extern Datum eqsel(PG_FUNCTION_ARGS);

View File

@ -103,11 +103,13 @@ WHERE p1.oid != p2.oid AND
(p1.proargtypes[0] < p2.proargtypes[0]);
proargtypes | proargtypes
-------------+-------------
25 | 1042
25 | 1043
1042 | 1043
1114 | 1184
1560 | 1562
2277 | 2283
(4 rows)
(6 rows)
SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
FROM pg_proc AS p1, pg_proc AS p2
@ -118,10 +120,13 @@ WHERE p1.oid != p2.oid AND
(p1.proargtypes[1] < p2.proargtypes[1]);
proargtypes | proargtypes
-------------+-------------
25 | 1042
25 | 1043
1042 | 1043
1114 | 1184
1560 | 1562
2277 | 2283
(3 rows)
(6 rows)
SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
FROM pg_proc AS p1, pg_proc AS p2
@ -332,7 +337,7 @@ WHERE p1.oprnegate = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprlsortop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '<' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprleft != p2.oprright OR
@ -345,7 +350,7 @@ WHERE p1.oprlsortop = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprrsortop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '<' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprright != p2.oprleft OR
p1.oprright != p2.oprright OR
@ -358,7 +363,7 @@ WHERE p1.oprrsortop = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprltcmpop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '<' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
@ -371,7 +376,7 @@ WHERE p1.oprltcmpop = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprgtcmpop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '>' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('>', '~>~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
@ -427,7 +432,7 @@ SELECT p1.oid, p1.oprname
FROM pg_operator AS p1
WHERE p1.oprcanhash AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
p1.oprleft = p1.oprright AND p1.oprname IN ('=', '~=~') AND p1.oprcom = p1.oid);
oid | oprname
-----+---------
353 | =

View File

@ -276,7 +276,7 @@ WHERE p1.oprnegate = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprlsortop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '<' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprleft != p2.oprright OR
@ -286,7 +286,7 @@ WHERE p1.oprlsortop = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprrsortop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '<' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprright != p2.oprleft OR
p1.oprright != p2.oprright OR
@ -296,7 +296,7 @@ WHERE p1.oprrsortop = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprltcmpop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '<' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
@ -306,7 +306,7 @@ WHERE p1.oprltcmpop = p2.oid AND
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
FROM pg_operator AS p1, pg_operator AS p2
WHERE p1.oprgtcmpop = p2.oid AND
(p1.oprname != '=' OR p2.oprname != '>' OR
(p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('>', '~>~') OR
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
@ -355,7 +355,7 @@ SELECT p1.oid, p1.oprname
FROM pg_operator AS p1
WHERE p1.oprcanhash AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
p1.oprleft = p1.oprright AND p1.oprname IN ('=', '~=~') AND p1.oprcom = p1.oid);
-- In 6.5 we accepted hashable array equality operators when the array element
-- type is hashable. However, what we actually need to make hashjoin work on