aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_oper.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-08-26 04:59:15 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-08-26 04:59:15 +0000
commit5adebf83b6cffbf4133ff97dbe6d5da0ff59bff1 (patch)
treecad98a9a3428b57e4146c39eaeb47df75592f9d1 /src/backend/parser/parse_oper.c
parent42af56e1ead3306d2c056ff96ea770e4eee68e9d (diff)
downloadpostgresql-5adebf83b6cffbf4133ff97dbe6d5da0ff59bff1.tar.gz
postgresql-5adebf83b6cffbf4133ff97dbe6d5da0ff59bff1.zip
Clean up some bugs in oper_select_candidate(), notably the
last loop which would return the *first* surviving-to-that-point candidate regardless of which one actually passed the test. This was producing such curious results as 'oid % 2' getting translated to 'int2(oid) % 2'.
Diffstat (limited to 'src/backend/parser/parse_oper.c')
-rw-r--r--src/backend/parser/parse_oper.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 529663b6ce5..8f82e58517d 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.30 1999/08/23 23:48:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.31 1999/08/26 04:59:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,9 +28,7 @@ static Oid *oper_select_candidate(int nargs, Oid *input_typeids,
static Operator oper_exact(char *op, Oid arg1, Oid arg2);
static Operator oper_inexact(char *op, Oid arg1, Oid arg2);
static int binary_oper_get_candidates(char *opname,
- Oid leftTypeId,
- Oid rightTypeId,
- CandidateList *candidates);
+ CandidateList *candidates);
static int unary_oper_get_candidates(char *op,
Oid typeId,
CandidateList *candidates,
@@ -64,15 +62,12 @@ oprid(Operator op)
/* binary_oper_get_candidates()
- * given opname, leftTypeId and rightTypeId,
- * find all possible (arg1, arg2) pairs for which an operator named
- * opname exists, such that leftTypeId can be coerced to arg1 and
- * rightTypeId can be coerced to arg2
+ * given opname, find all possible input type pairs for which an operator
+ * named opname exists. Build a list of the candidate input types.
+ * Returns number of candidates found.
*/
static int
binary_oper_get_candidates(char *opname,
- Oid leftTypeId,
- Oid rightTypeId,
CandidateList *candidates)
{
CandidateList current_candidate;
@@ -224,14 +219,17 @@ oper_select_candidate(int nargs,
ncandidates++;
}
/* otherwise, don't bother keeping this one... */
- else
- last_candidate->next = NULL;
}
+ if (last_candidate) /* terminate rebuilt list */
+ last_candidate->next = NULL;
+
if (ncandidates <= 1)
{
- if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0])
- || !can_coerce_type(1, &input_typeids[1], &candidates->args[1]))
+ if (ncandidates > 0 &&
+ (!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ||
+ (nargs > 1 &&
+ !can_coerce_type(1, &input_typeids[1], &candidates->args[1]))))
ncandidates = 0;
return (ncandidates == 1) ? candidates->args : NULL;
}
@@ -252,9 +250,9 @@ oper_select_candidate(int nargs,
nmatch = 0;
for (i = 0; i < nargs; i++)
{
- current_category = TypeCategory(current_typeids[i]);
if (input_typeids[i] != UNKNOWNOID)
{
+ current_category = TypeCategory(current_typeids[i]);
if (current_typeids[i] == input_typeids[i])
nmatch++;
else if (IsPreferredType(current_category, current_typeids[i])
@@ -276,14 +274,17 @@ oper_select_candidate(int nargs,
last_candidate = current_candidate;
ncandidates++;
}
- else
- last_candidate->next = NULL;
}
+ if (last_candidate) /* terminate rebuilt list */
+ last_candidate->next = NULL;
+
if (ncandidates <= 1)
{
- if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0])
- || ((nargs > 1) && !can_coerce_type(1, &input_typeids[1], &candidates->args[1])))
+ if (ncandidates > 0 &&
+ (!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ||
+ (nargs > 1 &&
+ !can_coerce_type(1, &input_typeids[1], &candidates->args[1]))))
ncandidates = 0;
return (ncandidates == 1) ? candidates->args : NULL;
}
@@ -309,12 +310,12 @@ oper_select_candidate(int nargs,
current_candidate != NULL;
current_candidate = current_candidate->next)
{
+ current_typeids = current_candidate->args;
nmatch = 0;
for (i = 0; i < nargs; i++)
{
- current_typeids = current_candidate->args;
- if ((current_type == current_typeids[i])
- || IS_BINARY_COMPATIBLE(current_type, current_typeids[i]))
+ if (current_type == current_typeids[i] ||
+ IS_BINARY_COMPATIBLE(current_type, current_typeids[i]))
nmatch++;
}
if (nmatch == nargs)
@@ -364,16 +365,20 @@ oper_select_candidate(int nargs,
}
ncandidates = 0;
+ last_candidate = NULL;
for (current_candidate = candidates;
current_candidate != NULL;
current_candidate = current_candidate->next)
{
if (can_coerce_type(1, &input_typeids[0], &current_candidate->args[0])
&& can_coerce_type(1, &input_typeids[1], &current_candidate->args[1]))
+ {
ncandidates++;
+ last_candidate = current_candidate;
+ }
}
- return (ncandidates == 1) ? candidates->args : NULL;
+ return (ncandidates == 1) ? last_candidate->args : NULL;
} /* oper_select_candidate() */
@@ -423,7 +428,7 @@ oper_inexact(char *op, Oid arg1, Oid arg2)
if (arg1 == InvalidOid)
arg1 = arg2;
- ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates);
+ ncandidates = binary_oper_get_candidates(op, &candidates);
/* No operators found? Then return null... */
if (ncandidates == 0)