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,
2828static Operator oper_exact (char * op ,Oid arg1 ,Oid arg2 );
2929static Operator oper_inexact (char * op ,Oid arg1 ,Oid arg2 );
3030static int binary_oper_get_candidates (char * opname ,
31- Oid leftTypeId ,
32- Oid rightTypeId ,
33- CandidateList * candidates );
31+ CandidateList * candidates );
3432static int unary_oper_get_candidates (char * op ,
3533Oid typeId ,
3634CandidateList * 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 */
7269static int
7370binary_oper_get_candidates (char * opname ,
74- Oid leftTypeId ,
75- Oid rightTypeId ,
7671CandidateList * candidates )
7772{
7873CandidateList current_candidate ;
@@ -224,14 +219,17 @@ oper_select_candidate(int nargs,
224219ncandidates ++ ;
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+
231227if (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 ]))))
235233ncandidates = 0 ;
236234return (ncandidates == 1 ) ?candidates -> args :NULL ;
237235}
@@ -252,9 +250,9 @@ oper_select_candidate(int nargs,
252250nmatch = 0 ;
253251for (i = 0 ;i < nargs ;i ++ )
254252{
255- current_category = TypeCategory (current_typeids [i ]);
256253if (input_typeids [i ]!= UNKNOWNOID )
257254{
255+ current_category = TypeCategory (current_typeids [i ]);
258256if (current_typeids [i ]== input_typeids [i ])
259257nmatch ++ ;
260258else if (IsPreferredType (current_category ,current_typeids [i ])
@@ -276,14 +274,17 @@ oper_select_candidate(int nargs,
276274last_candidate = current_candidate ;
277275ncandidates ++ ;
278276}
279- else
280- last_candidate -> next = NULL ;
281277}
282278
279+ if (last_candidate )/* terminate rebuilt list */
280+ last_candidate -> next = NULL ;
281+
283282if (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 ]))))
287288ncandidates = 0 ;
288289return (ncandidates == 1 ) ?candidates -> args :NULL ;
289290}
@@ -309,12 +310,12 @@ oper_select_candidate(int nargs,
309310current_candidate != NULL ;
310311current_candidate = current_candidate -> next )
311312{
313+ current_typeids = current_candidate -> args ;
312314nmatch = 0 ;
313315for (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 ]))
318319nmatch ++ ;
319320}
320321if (nmatch == nargs )
@@ -364,16 +365,20 @@ oper_select_candidate(int nargs,
364365}
365366
366367ncandidates = 0 ;
368+ last_candidate = NULL ;
367369for (current_candidate = candidates ;
368370current_candidate != NULL ;
369371current_candidate = current_candidate -> next )
370372{
371373if (can_coerce_type (1 ,& input_typeids [0 ],& current_candidate -> args [0 ])
372374&& can_coerce_type (1 ,& input_typeids [1 ],& current_candidate -> args [1 ]))
375+ {
373376ncandidates ++ ;
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)
423428if (arg1 == InvalidOid )
424429arg1 = 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... */
429434if (ncandidates == 0 )