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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy