From 24b83a5082541bdb1b333b7fcbe92f194128595c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 9 Nov 2020 12:02:24 -0500 Subject: [PATCH] Doc: clarify data type behavior of COALESCE and NULLIF. After studying the code, NULLIF is a lot more subtle than you might have guessed. Discussion: https://postgr.es/m/160486028730.25500.15740897403028593550@wrigleys.postgresql.org --- doc/src/sgml/func.sgml | 27 +++++++++++++++++++++++++-- doc/src/sgml/typeconv.sgml | 12 ++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 7b1dc264f6..2783985b55 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -17286,6 +17286,12 @@ SELECT COALESCE(description, short_description, '(none)') ... short_description if it is not null, otherwise (none). + + The arguments must all be convertible to a common data type, which + will be the type of the result (see + for details). + + Like a CASE expression, COALESCE only evaluates the arguments that are needed to determine the result; @@ -17316,13 +17322,30 @@ SELECT COALESCE(description, short_description, '(none)') ... SELECT NULLIF(value, '(none)') ... - - In this example, if value is (none), null is returned, otherwise the value of value is returned. + + The two arguments must be of comparable types. + To be specific, they are compared exactly as if you had + written value1 + = value2, so there must be a + suitable = operator available. + + + + The result has the same type as the first argument — but there is + a subtlety. What is actually returned is the first argument of the + implied = operator, and in some cases that will have + been promoted to match the second argument's type. For + example, NULLIF(1, 2.2) yields numeric, + because there is no integer = + numeric operator, + only numeric = numeric. + + diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index cfeb851a50..810b0cb557 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -127,8 +127,10 @@ must appear in a single set of columns, the types of the results of each SELECT clause must be matched up and converted to a uniform set. Similarly, the result expressions of a CASE construct must be converted to a common type so that the CASE expression as a whole -has a known output type. The same holds for ARRAY constructs, -and for the GREATEST and LEAST functions. +has a known output type. Some other constructs, such +as ARRAY[] and the GREATEST +and LEAST functions, likewise require determination of a +common type for several subexpressions. @@ -1040,9 +1042,11 @@ SQL UNION constructs must match up possibly dissimilar types to become a single result set. The resolution algorithm is applied separately to each output column of a union query. The INTERSECT and EXCEPT constructs resolve -dissimilar types in the same way as UNION. The +dissimilar types in the same way as UNION. +Some other constructs, including CASE, ARRAY, VALUES, -GREATEST and LEAST constructs use the identical +and the GREATEST and LEAST +functions, use the identical algorithm to match up their component expressions and select a result data type.