diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-03-11 23:17:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-03-11 23:17:47 +0000 |
commit | c9f287e49b0592adae224adff2232dd3e669b941 (patch) | |
tree | 0fb2010e5ece6ffa87953bfa411dd30f579ad939 /src/backend/parser/parse_func.c | |
parent | 1d75298176705edda237af75e24e0a87cfb9f6ad (diff) | |
download | postgresql-c9f287e49b0592adae224adff2232dd3e669b941.tar.gz postgresql-c9f287e49b0592adae224adff2232dd3e669b941.zip |
Further fixes for bogus list-slinging, scribbling on input, etc in type
coercion code. I'm beginning to wonder why we have separate candidate
selection routines for functions, operators, and aggregates --- shouldn't
this code all be unified? But meanwhile,
SELECT 'a' LIKE 'a';
finally works; the code for dealing with unknown input types for operators
was pretty busted.
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r-- | src/backend/parser/parse_func.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 1eeeb17c625..90c65a3830e 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.72 2000/02/20 23:04:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.73 2000/03/11 23:17:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -854,11 +854,6 @@ match_argtypes(int nargs, * for the function argtype array, attempt to resolve the conflict. * returns the selected argtype array if the conflict can be resolved, * otherwise returns NULL. - * - * If all input Oids are UNKNOWNOID, then try matching with TEXTOID. - * Otherwise, could return first function arguments on list of candidates. - * But for now, return NULL and make the user give a better hint. - * - thomas 1998-03-17 */ static Oid * func_select_candidate(int nargs, @@ -869,12 +864,10 @@ func_select_candidate(int nargs, CandidateList last_candidate; Oid *current_typeids; int i; - int ncandidates; int nbestMatch, nmatch, - nident; - + ncompat; CATEGORY slot_category, current_category; Oid slot_type, @@ -893,19 +886,29 @@ func_select_candidate(int nargs, { current_typeids = current_candidate->args; nmatch = 0; - nident = 0; + ncompat = 0; for (i = 0; i < nargs; i++) { - if ((input_typeids[i] != UNKNOWNOID) - && (current_typeids[i] == input_typeids[i])) - nmatch++; - else if (IS_BINARY_COMPATIBLE(current_typeids[i], input_typeids[i])) - nident++; + if (input_typeids[i] != UNKNOWNOID) + { + if (current_typeids[i] == input_typeids[i]) + nmatch++; + else if (IS_BINARY_COMPATIBLE(current_typeids[i], + input_typeids[i])) + ncompat++; + } } - if ((nmatch + nident) == nargs) + /* + * If we find an exact match at all arg positions, we're done; + * there can be only one such candidate. + */ + if (nmatch == nargs) return current_candidate->args; + /* Otherwise, use match+compat as the score. */ + nmatch += ncompat; + /* take this one as the best choice so far? */ if ((nmatch > nbestMatch) || (last_candidate == NULL)) { @@ -933,6 +936,16 @@ func_select_candidate(int nargs, /* * Still too many candidates? * Try assigning types for the unknown columns. + * + * We do this by examining each unknown argument position to see if all the + * candidates agree on the type category of that slot. If so, and if some + * candidates accept the preferred type in that category, eliminate the + * candidates with other input types. If we are down to one candidate + * at the end, we win. + * + * XXX It's kinda bogus to do this left-to-right, isn't it? If we eliminate + * some candidates because they are non-preferred at the first slot, we won't + * notice that they didn't have the same type category for a later slot. */ for (i = 0; i < nargs; i++) { @@ -947,12 +960,12 @@ func_select_candidate(int nargs, { current_typeids = current_candidate->args; current_type = current_typeids[i]; - current_category = TypeCategory(current_typeids[i]); - - if (slot_category == InvalidOid) + current_category = TypeCategory(current_type); + if (slot_category == INVALID_TYPE) { slot_category = current_category; slot_type = current_type; + last_candidate = current_candidate; } else if (current_category != slot_category) { |