summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_oper.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-06-27 00:33:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-06-27 00:33:26 +0000
commitb3c0551edaf390ab7bde4ebcc2299d1b0da686c5 (patch)
tree46512d8ab2d8eeb570722878904f367effb1383d /src/backend/parser/parse_oper.c
parent0c985ab5a86b4ca9d8e312bfd0db5536b2be121e (diff)
Create real array comparison functions (that use the element datatype's
comparison functions), replacing the highly bogus bitwise array_eq. Create a btree index opclass for ANYARRAY --- it is now possible to create indexes on array columns. Arrange to cache the results of catalog lookups across multiple array operations, instead of repeating the lookups on every call. Add string_to_array and array_to_string functions. Remove singleton_array, array_accum, array_assign, and array_subscript functions, since these were for proof-of-concept and not intended to become supported functions. Minor adjustments to behavior in some corner cases with empty or zero-dimensional arrays. Joe Conway (with some editorializing by Tom Lane).
Diffstat (limited to 'src/backend/parser/parse_oper.c')
-rw-r--r--src/backend/parser/parse_oper.c122
1 files changed, 91 insertions, 31 deletions
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 69edb4b85bd..983041eb45b 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.66 2003/06/25 21:30:32 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.67 2003/06/27 00:33:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -137,28 +137,50 @@ Operator
equality_oper(Oid argtype, bool noError)
{
Operator optup;
+ Oid elem_type;
/*
- * Look for an "=" operator for the datatype. We require it to be
- * an exact or binary-compatible match, since most callers are not
- * prepared to cope with adding any run-time type coercion steps.
+ * If the datatype is an array, then we can use array_eq ... but only
+ * if there is a suitable equality operator for the element type.
+ * (We must run this test first, since compatible_oper will find
+ * array_eq, but would not notice the lack of an element operator.)
*/
- optup = compatible_oper(makeList1(makeString("=")),
- argtype, argtype, true);
- if (optup != NULL)
+ elem_type = get_element_type(argtype);
+ if (OidIsValid(elem_type))
+ {
+ optup = equality_oper(elem_type, true);
+ if (optup != NULL)
+ {
+ ReleaseSysCache(optup);
+ return SearchSysCache(OPEROID,
+ ObjectIdGetDatum(ARRAY_EQ_OP),
+ 0, 0, 0);
+ }
+ }
+ else
{
/*
- * Only believe that it's equality if it's mergejoinable,
- * hashjoinable, or uses eqsel() as oprrest.
+ * Look for an "=" operator for the datatype. We require it to be
+ * an exact or binary-compatible match, since most callers are not
+ * prepared to cope with adding any run-time type coercion steps.
*/
- Form_pg_operator pgopform = (Form_pg_operator) GETSTRUCT(optup);
+ optup = compatible_oper(makeList1(makeString("=")),
+ argtype, argtype, true);
+ if (optup != NULL)
+ {
+ /*
+ * Only believe that it's equality if it's mergejoinable,
+ * hashjoinable, or uses eqsel() as oprrest.
+ */
+ Form_pg_operator pgopform = (Form_pg_operator) GETSTRUCT(optup);
- if (OidIsValid(pgopform->oprlsortop) ||
- pgopform->oprcanhash ||
- pgopform->oprrest == F_EQSEL)
- return optup;
+ if (OidIsValid(pgopform->oprlsortop) ||
+ pgopform->oprcanhash ||
+ pgopform->oprrest == F_EQSEL)
+ return optup;
- ReleaseSysCache(optup);
+ ReleaseSysCache(optup);
+ }
}
if (!noError)
elog(ERROR, "Unable to identify an equality operator for type %s",
@@ -175,27 +197,50 @@ Operator
ordering_oper(Oid argtype, bool noError)
{
Operator optup;
+ Oid elem_type;
/*
- * Find the type's equality operator, and use its lsortop (it *must*
- * be mergejoinable). We use this definition because for sorting and
- * grouping purposes, it's important that the equality and ordering
- * operators are consistent.
+ * If the datatype is an array, then we can use array_lt ... but only
+ * if there is a suitable ordering operator for the element type.
+ * (We must run this test first, since the code below would find
+ * array_lt if there's an element = operator, but would not notice the
+ * lack of an element < operator.)
*/
- optup = equality_oper(argtype, noError);
- if (optup != NULL)
+ elem_type = get_element_type(argtype);
+ if (OidIsValid(elem_type))
{
- Oid lsortop = ((Form_pg_operator) GETSTRUCT(optup))->oprlsortop;
-
- ReleaseSysCache(optup);
-
- if (OidIsValid(lsortop))
+ optup = ordering_oper(elem_type, true);
+ if (optup != NULL)
{
- optup = SearchSysCache(OPEROID,
- ObjectIdGetDatum(lsortop),
- 0, 0, 0);
- if (optup != NULL)
- return optup;
+ ReleaseSysCache(optup);
+ return SearchSysCache(OPEROID,
+ ObjectIdGetDatum(ARRAY_LT_OP),
+ 0, 0, 0);
+ }
+ }
+ else
+ {
+ /*
+ * Find the type's equality operator, and use its lsortop (it *must*
+ * be mergejoinable). We use this definition because for sorting and
+ * grouping purposes, it's important that the equality and ordering
+ * operators are consistent.
+ */
+ optup = equality_oper(argtype, noError);
+ if (optup != NULL)
+ {
+ Oid lsortop;
+
+ lsortop = ((Form_pg_operator) GETSTRUCT(optup))->oprlsortop;
+ ReleaseSysCache(optup);
+ if (OidIsValid(lsortop))
+ {
+ optup = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(lsortop),
+ 0, 0, 0);
+ if (optup != NULL)
+ return optup;
+ }
}
}
if (!noError)
@@ -237,6 +282,21 @@ ordering_oper_opid(Oid argtype)
return result;
}
+/*
+ * ordering_oper_funcid - convenience routine for oprfuncid(ordering_oper())
+ */
+Oid
+ordering_oper_funcid(Oid argtype)
+{
+ Operator optup;
+ Oid result;
+
+ optup = ordering_oper(argtype, false);
+ result = oprfuncid(optup);
+ ReleaseSysCache(optup);
+ return result;
+}
+
/* given operator tuple, return the operator OID */
Oid