Skip to content

Commit 5adebf8

Browse files
committed
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'.
1 parent 42af56e commit 5adebf8

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

src/backend/parser/parse_oper.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.30 1999/08/23 23:48:39 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.31 1999/08/26 04:59:15 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -28,9 +28,7 @@ static Oid *oper_select_candidate(int nargs, Oid *input_typeids,
2828
static Operator oper_exact(char *op, Oid arg1, Oid arg2);
2929
static Operator oper_inexact(char *op, Oid arg1, Oid arg2);
3030
static int binary_oper_get_candidates(char *opname,
31-
Oid leftTypeId,
32-
Oid rightTypeId,
33-
CandidateList *candidates);
31+
CandidateList *candidates);
3432
static int unary_oper_get_candidates(char *op,
3533
Oid typeId,
3634
CandidateList *candidates,
@@ -64,15 +62,12 @@ oprid(Operator op)
6462

6563

6664
/* binary_oper_get_candidates()
67-
* given opname, leftTypeId and rightTypeId,
68-
* find all possible (arg1, arg2) pairs for which an operator named
69-
* opname exists, such that leftTypeId can be coerced to arg1 and
70-
* rightTypeId can be coerced to arg2
65+
* given opname, find all possible input type pairs for which an operator
66+
* named opname exists. Build a list of the candidate input types.
67+
* Returns number of candidates found.
7168
*/
7269
static int
7370
binary_oper_get_candidates(char *opname,
74-
Oid leftTypeId,
75-
Oid rightTypeId,
7671
CandidateList *candidates)
7772
{
7873
CandidateList current_candidate;
@@ -224,14 +219,17 @@ oper_select_candidate(int nargs,
224219
ncandidates++;
225220
}
226221
/* otherwise, don't bother keeping this one... */
227-
else
228-
last_candidate->next = NULL;
229222
}
230223

224+
if (last_candidate) /* terminate rebuilt list */
225+
last_candidate->next = NULL;
226+
231227
if (ncandidates <= 1)
232228
{
233-
if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0])
234-
|| !can_coerce_type(1, &input_typeids[1], &candidates->args[1]))
229+
if (ncandidates > 0 &&
230+
(!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ||
231+
(nargs > 1 &&
232+
!can_coerce_type(1, &input_typeids[1], &candidates->args[1]))))
235233
ncandidates = 0;
236234
return (ncandidates == 1) ? candidates->args : NULL;
237235
}
@@ -252,9 +250,9 @@ oper_select_candidate(int nargs,
252250
nmatch = 0;
253251
for (i = 0; i < nargs; i++)
254252
{
255-
current_category = TypeCategory(current_typeids[i]);
256253
if (input_typeids[i] != UNKNOWNOID)
257254
{
255+
current_category = TypeCategory(current_typeids[i]);
258256
if (current_typeids[i] == input_typeids[i])
259257
nmatch++;
260258
else if (IsPreferredType(current_category, current_typeids[i])
@@ -276,14 +274,17 @@ oper_select_candidate(int nargs,
276274
last_candidate = current_candidate;
277275
ncandidates++;
278276
}
279-
else
280-
last_candidate->next = NULL;
281277
}
282278

279+
if (last_candidate) /* terminate rebuilt list */
280+
last_candidate->next = NULL;
281+
283282
if (ncandidates <= 1)
284283
{
285-
if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0])
286-
|| ((nargs > 1) && !can_coerce_type(1, &input_typeids[1], &candidates->args[1])))
284+
if (ncandidates > 0 &&
285+
(!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ||
286+
(nargs > 1 &&
287+
!can_coerce_type(1, &input_typeids[1], &candidates->args[1]))))
287288
ncandidates = 0;
288289
return (ncandidates == 1) ? candidates->args : NULL;
289290
}
@@ -309,12 +310,12 @@ oper_select_candidate(int nargs,
309310
current_candidate != NULL;
310311
current_candidate = current_candidate->next)
311312
{
313+
current_typeids = current_candidate->args;
312314
nmatch = 0;
313315
for (i = 0; i < nargs; i++)
314316
{
315-
current_typeids = current_candidate->args;
316-
if ((current_type == current_typeids[i])
317-
|| IS_BINARY_COMPATIBLE(current_type, current_typeids[i]))
317+
if (current_type == current_typeids[i] ||
318+
IS_BINARY_COMPATIBLE(current_type, current_typeids[i]))
318319
nmatch++;
319320
}
320321
if (nmatch == nargs)
@@ -364,16 +365,20 @@ oper_select_candidate(int nargs,
364365
}
365366

366367
ncandidates = 0;
368+
last_candidate = NULL;
367369
for (current_candidate = candidates;
368370
current_candidate != NULL;
369371
current_candidate = current_candidate->next)
370372
{
371373
if (can_coerce_type(1, &input_typeids[0], &current_candidate->args[0])
372374
&& can_coerce_type(1, &input_typeids[1], &current_candidate->args[1]))
375+
{
373376
ncandidates++;
377+
last_candidate = current_candidate;
378+
}
374379
}
375380

376-
return (ncandidates == 1) ? candidates->args : NULL;
381+
return (ncandidates == 1) ? last_candidate->args : NULL;
377382
} /* oper_select_candidate() */
378383

379384

@@ -423,7 +428,7 @@ oper_inexact(char *op, Oid arg1, Oid arg2)
423428
if (arg1 == InvalidOid)
424429
arg1 = arg2;
425430

426-
ncandidates = binary_oper_get_candidates(op, arg1, arg2, &candidates);
431+
ncandidates = binary_oper_get_candidates(op, &candidates);
427432

428433
/* No operators found? Then return null... */
429434
if (ncandidates == 0)

0 commit comments

Comments
 (0)