88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.36 2000/02/27 02:48:15 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.37 2000/03/11 23:17:47 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -128,7 +128,7 @@ binary_oper_get_candidates(char *opname,
128128 *
129129 * This routine is new code, replacing binary_oper_select_candidate()
130130 * which dates from v4.2/v1.0.x days. It tries very hard to match up
131- * operators with types, including allowing typecoersions if necessary.
131+ * operators with types, including allowing typecoercions if necessary.
132132 * The important thing is that the code do as much as possible,
133133 * while _never_ doing the wrong thing, where "the wrong thing" would
134134 * be returning an operator when other better choices are available,
@@ -185,7 +185,7 @@ oper_select_candidate(int nargs,
185185
186186/*
187187 * Run through all candidates and keep those with the most matches
188- *onexplicit types. Keep all candidates if none match.
188+ *onexact types. Keep all candidates if none match.
189189 */
190190ncandidates = 0 ;
191191nbestMatch = 0 ;
@@ -236,7 +236,7 @@ oper_select_candidate(int nargs,
236236
237237/*
238238 * Still too many candidates?
239- * Now look for candidates which allowcoersion and are preferred types.
239+ * Now look for candidates which allowcoercion and are preferred types.
240240 * Keep all candidates if none match.
241241 */
242242ncandidates = 0 ;
@@ -292,6 +292,13 @@ oper_select_candidate(int nargs,
292292/*
293293 * Still too many candidates?
294294 * Try assigning types for the unknown columns.
295+ *
296+ * First try: if we have an unknown and a non-unknown input, see whether
297+ * there is a candidate all of whose input types are the same as the known
298+ * input type (there can be at most one such candidate). If so, use that
299+ * candidate. NOTE that this is cool only because operators can't
300+ * have more than 2 args, so taking the last non-unknown as current_type
301+ * can yield only one possibility if there is also an unknown.
295302 */
296303unknownOids = FALSE;
297304current_type = UNKNOWNOID ;
@@ -314,53 +321,82 @@ oper_select_candidate(int nargs,
314321nmatch = 0 ;
315322for (i = 0 ;i < nargs ;i ++ )
316323{
317- if (current_type == current_typeids [i ]||
318- IS_BINARY_COMPATIBLE (current_type ,current_typeids [i ]))
324+ if (current_type == current_typeids [i ])
319325nmatch ++ ;
320326}
321327if (nmatch == nargs )
322- return candidates -> args ;
328+ {
329+ /* coercion check here is probably redundant, but be safe */
330+ if (can_coerce_type (nargs ,input_typeids ,current_typeids ))
331+ return current_typeids ;
332+ }
323333}
324334}
325335
336+ /*
337+ * Second try: examine each unknown argument position to see if all the
338+ * candidates agree on the type category of that slot. If so, and if some
339+ * candidates accept the preferred type in that category, eliminate the
340+ * candidates with other input types. If we are down to one candidate
341+ * at the end, we win.
342+ *
343+ * XXX It's kinda bogus to do this left-to-right, isn't it? If we eliminate
344+ * some candidates because they are non-preferred at the first slot, we won't
345+ * notice that they didn't have the same type category for a later slot.
346+ */
326347for (i = 0 ;i < nargs ;i ++ )
327348{
328349if (input_typeids [i ]== UNKNOWNOID )
329350{
330351slot_category = INVALID_TYPE ;
331352slot_type = InvalidOid ;
353+ last_candidate = NULL ;
332354for (current_candidate = candidates ;
333355current_candidate != NULL ;
334356current_candidate = current_candidate -> next )
335357{
336358current_typeids = current_candidate -> args ;
337359current_type = current_typeids [i ];
338- current_category = TypeCategory (current_typeids [ i ] );
339- if (slot_category == InvalidOid )
360+ current_category = TypeCategory (current_type );
361+ if (slot_category == INVALID_TYPE )
340362{
341363slot_category = current_category ;
342364slot_type = current_type ;
365+ last_candidate = current_candidate ;
343366}
344367else if (current_category != slot_category )
368+ {
369+ /* punt if more than one category for this slot */
345370return NULL ;
371+ }
346372else if (current_type != slot_type )
347373{
348374if (IsPreferredType (slot_category ,current_type ))
349375{
350376slot_type = current_type ;
377+ /* forget all previous candidates */
351378candidates = current_candidate ;
379+ last_candidate = current_candidate ;
352380}
353- else
381+ else if ( IsPreferredType ( slot_category , slot_type ))
354382{
383+ /* forget this candidate */
384+ if (last_candidate )
385+ last_candidate -> next = current_candidate -> next ;
386+ else
387+ candidates = current_candidate -> next ;
355388}
389+ else
390+ last_candidate = current_candidate ;
391+ }
392+ else
393+ {
394+ /* keep this candidate */
395+ last_candidate = current_candidate ;
356396}
357397}
358-
359- if (slot_type != InvalidOid )
360- input_typeids [i ]= slot_type ;
361- }
362- else
363- {
398+ if (last_candidate )/* terminate rebuilt list */
399+ last_candidate -> next = NULL ;
364400}
365401}
366402