linkend="sql-precedence"> for more information.
If any input arguments are unknown
, check the type
categories accepted at those argument positions by the remaining
-candidates. At each position, try the "string" category if any
+candidates. At each position, select the "string" category if any
candidate accepts that category (this bias towards string is appropriate
since an unknown-type literal does look like a string). Otherwise, if
all the remaining candidates accept the same type category, select that
-One unspecified argument:
+An example with one unspecified argument:
tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
Text and Unknown
-
Factorial Operator Type Resolution
+
Absolute-Value and Factorial Operator Type Resolution
-This example illustrates an interesting result. Traditionally, the
-factorial operator is defined for integers only. The
PostgreSQL
-operator catalog has only one entry for factorial, taking an integer operand.
-If given a non-integer numeric argument,
PostgreSQL
-will try to convert that argument to an integer for evaluation of the
-factorial.
-
+The
PostgreSQL operator catalog has several
+entries for the prefix operator @>, all of which implement
+absolute-value operations for various numeric datatypes. One of these
+entries is for type float8, which is the preferred type in
+the numeric category. Therefore,
PostgreSQL
+will use that entry when faced with a non-numeric input:
-tgl=> SELECT (4.3 !);
- ?column?
-----------
- 24
+tgl=> select @ text '-4.5' as "abs";
+ abs
+-----
+ 4.5
(1 row)
+Here the system has performed an implicit text-to-float8 conversion
+before applying the chosen operator. We can verify that float8 and
+not some other type was used:
+
+tgl=> select @ text '-4.5e500' as "abs";
+ERROR: Input '-4.5e500' is out of range for float8
+
+
-
-Of course, this leads to a mathematically suspect result,
-since in principle the factorial of a non-integer is not defined.
-However, the role of a database is not to teach mathematics, but
-to be a tool for data manipulation. If a user chooses to take the
-factorial of a floating point number,
PostgreSQL
-will try to oblige.
-
-
+On the other hand, the postfix operator !> (factorial)
+is defined only for integer datatypes, not for float8. So, if we
+try a similar case with !>, we get:
+
+tgl=> select text '44' ! as "factorial";
+ERROR: Unable to identify a postfix operator '!' for type 'text'
+ You may need to add parentheses or an explicit cast
+
+This happens because the system can't decide which of the several
+possible !> operators should be preferred. We can help
+it out with an explicit cast:
+
+tgl=> select cast(text '44' as int8) ! as "factorial";
+ factorial
+---------------------
+ 2673996885588443136
+(1 row)
+
If any input arguments are unknown, check the type categories accepted
at those argument positions by the remaining candidates. At each position,
-try the string category if any candidate accepts that category (this bias towards string
+select the string category if any candidate accepts that category
+(this bias towards string
is appropriate since an unknown-type literal does look like a string).
Otherwise, if all the remaining candidates accept the same type category,
select that category; otherwise fail because
the correct choice cannot be deduced without more clues. Also note whether
any of the candidates accept a preferred data type within the selected category.
-Now discard operator candidates that do not accept the selected type category;
+Now discard candidates that do not accept the selected type category;
furthermore, if any candidate accepts a preferred type at a given argument
position, discard candidates that accept non-preferred types for that
argument.
Factorial Function Argument Type Resolution
-There is only one factorial function defined in the pg_proc catalog.
+There is only one int4fac function defined in the
+pg_proc catalog.
So the following query automatically converts the int2 argument
to int4:
34
(1 row)
-actually executes as
+which actually executes as
tgl=> SELECT substr(text(1234), 3);
substr
Query Targets
+ Values to be inserted into a table are coerced to the destination
+ column's datatype according to the
+ following steps.
+
+
Query Target Type Resolution
-
varchar Storage Type Conversion
+
character Storage Type Conversion
-For a target column declared as varchar(4) the following query
+For a target column declared as character(20) the following query
ensures that the target is sized correctly:
-tgl=> CREATE TABLE vv (v varchar(4));
+tgl=> CREATE TABLE vv (v character(20));
CREATE
tgl=> INSERT INTO vv SELECT 'abc' || 'def';
INSERT 392905 1
-tgl=> SELECT * FROM vv;
- v
-------
- abcd
+tgl=> SELECT v, length(v) FROM vv;
+ v | length
+----------------------+--------
+ abcdef | 20
(1 row)
What has really happened here is that the two unknown literals are resolved
-to text by default, allowing the || operator to be
-resolved as text concatenation. Then the text result of the operator
-is coerced to varchar to match the target column type. (But, since the
-parser knows that text and varchar are binary-compatible, this coercion
-is implicit and does not insert any real function call.) Finally, the
-sizing function varchar(varchar, integer) is found in the system
-catalogs and applied to the operator's result and the stored column length.
-This type-specific function performs the desired truncation.
+to text by default, allowing the || operator
+to be resolved as text concatenation. Then the text
+result of the operator is coerced to bpchar (blank-padded
+char>, the internal name of the character datatype) to match the target
+column type. (Since the parser knows that text and
+bpchar are binary-compatible, this coercion is implicit and does
+not insert any real function call.) Finally, the sizing function
+bpchar(bpchar, integer) is found in the system catalogs
+and applied to the operator's result and the stored column length. This
+type-specific function performs the required length check and addition of
+padding spaces.
UNION> and CASE> Constructs
-The UNION> and CASE> 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. CASE> uses the identical algorithm to match
-up its result expressions.
+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>.
+A CASE> construct also uses the identical algorithm to match up its
+component expressions and select a result datatype.
UNION> and CASE> Type Resolution
1.2
(2 rows)
+The literal 1.2> is of type double precision>,
+the preferred type in the numeric category, so that type is used.
Here the output type of the union is forced to match the type of
-the first/top clause in the union:
+the first clause in the union:
tgl=> SELECT 1 AS "All integers"