From 1a8b9fb5499d8646661a57edd3c88c3107622ff8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 17 Nov 2011 18:28:41 -0500 Subject: Extend the unknowns-are-same-as-known-inputs type resolution heuristic. For a very long time, one of the parser's heuristics for resolving ambiguous operator calls has been to assume that unknown-type literals are of the same type as the other input (if it's known). However, this was only used in the first step of quickly checking for an exact-types match, and thus did not help in resolving matches that require coercion, such as matches to polymorphic operators. As we add more polymorphic operators, this becomes more of a problem. This patch adds another use of the same heuristic as a last-ditch check before failing to resolve an ambiguous operator or function call. In particular this will let us define the range inclusion operator in a less limited way (to come in a follow-on patch). --- doc/src/sgml/typeconv.sgml | 56 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 8 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index cca45eb5698..d040ec80933 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -304,13 +304,18 @@ without more clues. Now discard candidates that do not accept the selected type category. Furthermore, if any candidate accepts a preferred type in that category, discard candidates that accept non-preferred types for that argument. +Keep all candidates if none survive these tests. +If only one candidate remains, use it; else continue to the next step. -If only one candidate remains, use it. If no candidate or more than one -candidate remains, -then fail. +If there are both unknown and known-type arguments, and all +the known-type arguments have the same type, assume that the +unknown arguments are also of that type, and check which +candidates can accept that type at the unknown-argument +positions. If exactly one candidate passes this test, use it. +Otherwise, fail. @@ -376,7 +381,7 @@ be interpreted as type text. -Here is a concatenation on unspecified types: +Here is a concatenation of two values of unspecified types: SELECT 'abc' || 'def' AS "unspecified"; @@ -394,7 +399,7 @@ and finds that there are candidates accepting both string-category and bit-string-category inputs. Since string category is preferred when available, that category is selected, and then the preferred type for strings, text, is used as the specific -type to resolve the unknown literals as. +type to resolve the unknown-type literals as. @@ -450,6 +455,36 @@ SELECT ~ CAST('20' AS int8) AS "negation"; + +Array Inclusion Operator Type Resolution + + +Here is another example of resolving an operator with one known and one +unknown input: + +SELECT array[1,2] <@ '{1,2,3}' as "is subset"; + + is subset +----------- + t +(1 row) + +The PostgreSQL operator catalog has several +entries for the infix operator <@, but the only two that +could possibly accept an integer array on the left-hand side are +array inclusion (anyarray <@ anyarray) +and range inclusion (anyelement <@ anyrange). +Since none of these polymorphic pseudo-types (see ) are considered preferred, the parser cannot +resolve the ambiguity on that basis. However, the last resolution rule tells +it to assume that the unknown-type literal is of the same type as the other +input, that is, integer array. Now only one of the two operators can match, +so array inclusion is selected. (Had range inclusion been selected, we would +have gotten an error, because the string does not have the right format to be +a range literal.) + + + @@ -594,13 +629,18 @@ the correct choice cannot be deduced without more clues. Now discard candidates that do not accept the selected type category. Furthermore, if any candidate accepts a preferred type in that category, discard candidates that accept non-preferred types for that argument. +Keep all candidates if none survive these tests. +If only one candidate remains, use it; else continue to the next step. -If only one candidate remains, use it. If no candidate or more than one -candidate remains, -then fail. +If there are both unknown and known-type arguments, and all +the known-type arguments have the same type, assume that the +unknown arguments are also of that type, and check which +candidates can accept that type at the unknown-argument +positions. If exactly one candidate passes this test, use it. +Otherwise, fail. -- cgit v1.2.3