@@ -618,14 +618,16 @@ func_select_candidate(int nargs,
618
618
Oid * input_typeids ,
619
619
FuncCandidateList candidates )
620
620
{
621
- FuncCandidateList current_candidate ;
622
- FuncCandidateList last_candidate ;
621
+ FuncCandidateList current_candidate ,
622
+ first_candidate ,
623
+ last_candidate ;
623
624
Oid * current_typeids ;
624
625
Oid current_type ;
625
626
int i ;
626
627
int ncandidates ;
627
628
int nbestMatch ,
628
- nmatch ;
629
+ nmatch ,
630
+ nunknowns ;
629
631
Oid input_base_typeids [FUNC_MAX_ARGS ];
630
632
TYPCATEGORY slot_category [FUNC_MAX_ARGS ],
631
633
current_category ;
@@ -651,9 +653,22 @@ func_select_candidate(int nargs,
651
653
* take a domain as an input datatype. Such a function will be selected
652
654
* over the base-type function only if it is an exact match at all
653
655
* argument positions, and so was already chosen by our caller.
656
+ *
657
+ * While we're at it, count the number of unknown-type arguments for use
658
+ * later.
654
659
*/
660
+ nunknowns = 0 ;
655
661
for (i = 0 ; i < nargs ; i ++ )
656
- input_base_typeids [i ] = getBaseType (input_typeids [i ]);
662
+ {
663
+ if (input_typeids [i ] != UNKNOWNOID )
664
+ input_base_typeids [i ] = getBaseType (input_typeids [i ]);
665
+ else
666
+ {
667
+ /* no need to call getBaseType on UNKNOWNOID */
668
+ input_base_typeids [i ] = UNKNOWNOID ;
669
+ nunknowns ++ ;
670
+ }
671
+ }
657
672
658
673
/*
659
674
* Run through all candidates and keep those with the most matches on
@@ -749,14 +764,16 @@ func_select_candidate(int nargs,
749
764
return candidates ;
750
765
751
766
/*
752
- * Still too many candidates? Try assigning types for the unknown columns.
753
- *
754
- * NOTE: for a binary operator with one unknown and one non-unknown input,
755
- * we already tried the heuristic of looking for a candidate with the
756
- * known input type on both sides (see binary_oper_exact()). That's
757
- * essentially a special case of the general algorithm we try next.
767
+ * Still too many candidates? Try assigning types for the unknown inputs.
758
768
*
759
- * We do this by examining each unknown argument position to see if we can
769
+ * If there are no unknown inputs, we have no more heuristics that apply,
770
+ * and must fail.
771
+ */
772
+ if (nunknowns == 0 )
773
+ return NULL ; /* failed to select a best candidate */
774
+
775
+ /*
776
+ * The next step examines each unknown argument position to see if we can
760
777
* determine a "type category" for it. If any candidate has an input
761
778
* datatype of STRING category, use STRING category (this bias towards
762
779
* STRING is appropriate since unknown-type literals look like strings).
@@ -770,9 +787,9 @@ func_select_candidate(int nargs,
770
787
* Having completed this examination, remove candidates that accept the
771
788
* wrong category at any unknown position. Also, if at least one
772
789
* candidate accepted a preferred type at a position, remove candidates
773
- * that accept non-preferred types.
774
- *
775
- * If we are down to one candidate at the end, we win .
790
+ * that accept non-preferred types. If just one candidate remains,
791
+ * return that one. However, if this rule turns out to reject all
792
+ * candidates, keep them all instead .
776
793
*/
777
794
resolved_unknowns = false;
778
795
for (i = 0 ; i < nargs ; i ++ )
@@ -835,6 +852,7 @@ func_select_candidate(int nargs,
835
852
{
836
853
/* Strip non-matching candidates */
837
854
ncandidates = 0 ;
855
+ first_candidate = candidates ;
838
856
last_candidate = NULL ;
839
857
for (current_candidate = candidates ;
840
858
current_candidate != NULL ;
@@ -874,15 +892,78 @@ func_select_candidate(int nargs,
874
892
if (last_candidate )
875
893
last_candidate -> next = current_candidate -> next ;
876
894
else
877
- candidates = current_candidate -> next ;
895
+ first_candidate = current_candidate -> next ;
878
896
}
879
897
}
880
- if (last_candidate ) /* terminate rebuilt list */
898
+
899
+ /* if we found any matches, restrict our attention to those */
900
+ if (last_candidate )
901
+ {
902
+ candidates = first_candidate ;
903
+ /* terminate rebuilt list */
881
904
last_candidate -> next = NULL ;
905
+ }
906
+
907
+ if (ncandidates == 1 )
908
+ return candidates ;
882
909
}
883
910
884
- if (ncandidates == 1 )
885
- return candidates ;
911
+ /*
912
+ * Last gasp: if there are both known- and unknown-type inputs, and all
913
+ * the known types are the same, assume the unknown inputs are also that
914
+ * type, and see if that gives us a unique match. If so, use that match.
915
+ *
916
+ * NOTE: for a binary operator with one unknown and one non-unknown input,
917
+ * we already tried this heuristic in binary_oper_exact(). However, that
918
+ * code only finds exact matches, whereas here we will handle matches that
919
+ * involve coercion, polymorphic type resolution, etc.
920
+ */
921
+ if (nunknowns < nargs )
922
+ {
923
+ Oid known_type = UNKNOWNOID ;
924
+
925
+ for (i = 0 ; i < nargs ; i ++ )
926
+ {
927
+ if (input_base_typeids [i ] == UNKNOWNOID )
928
+ continue ;
929
+ if (known_type == UNKNOWNOID ) /* first known arg? */
930
+ known_type = input_base_typeids [i ];
931
+ else if (known_type != input_base_typeids [i ])
932
+ {
933
+ /* oops, not all match */
934
+ known_type = UNKNOWNOID ;
935
+ break ;
936
+ }
937
+ }
938
+
939
+ if (known_type != UNKNOWNOID )
940
+ {
941
+ /* okay, just one known type, apply the heuristic */
942
+ for (i = 0 ; i < nargs ; i ++ )
943
+ input_base_typeids [i ] = known_type ;
944
+ ncandidates = 0 ;
945
+ last_candidate = NULL ;
946
+ for (current_candidate = candidates ;
947
+ current_candidate != NULL ;
948
+ current_candidate = current_candidate -> next )
949
+ {
950
+ current_typeids = current_candidate -> args ;
951
+ if (can_coerce_type (nargs , input_base_typeids , current_typeids ,
952
+ COERCION_IMPLICIT ))
953
+ {
954
+ if (++ ncandidates > 1 )
955
+ break ; /* not unique, give up */
956
+ last_candidate = current_candidate ;
957
+ }
958
+ }
959
+ if (ncandidates == 1 )
960
+ {
961
+ /* successfully identified a unique match */
962
+ last_candidate -> next = NULL ;
963
+ return last_candidate ;
964
+ }
965
+ }
966
+ }
886
967
887
968
return NULL ; /* failed to select a best candidate */
888
969
} /* func_select_candidate() */
0 commit comments