+ linkend="sql-precedence"> for more information.
+
+
-
Operator Type Resolution
+
Operand Type Resolution
-Check for an exact match in the pg_operator system catalog.
+Check for an exact match in the pg_operator system catalog.
-
-
Examples
+Examples
-<sect3>
-
Exponentiation Operator
+<example>
+
Exponentiation Operator Type Resolution
There is only one exponentiation
operator defined in the catalog, and it takes arguments of type
double precision.
-The scanner assigns an initial type of int4 to both arguments
+The scanner assigns an initial type of integer to both arguments
of this query expression:
-<programlisting>
+<screen>
tgl=> select 2 ^ 3 AS "Exp";
Exp
-----
8
(1 row)
-programlisting>
+screen>
So the parser does a type conversion on both operands and the query
is equivalent to
-<programlisting>
+<screen>
tgl=> select CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp";
Exp
-----
8
(1 row)
-programlisting>
+screen>
or
-<programlisting>
+<screen>
tgl=> select 2.0 ^ 3.0 AS "Exp";
Exp
-----
8
(1 row)
-programlisting>
+screen>
-sect3>
+example>
-<sect3>
-
String Concatenation
+<example>
+
String Concatenation Operator Type Resolution
A string-like syntax is used for working with string types as well as for
One unspecified argument:
-<programlisting>
+<screen>
tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
Text and Unknown
------------------
abcdef
(1 row)
-programlisting>
+screen>
Concatenation on unspecified types:
-<programlisting>
+<screen>
tgl=> SELECT 'abc' || 'def' AS "Unspecified";
Unspecified
-------------
abcdef
(1 row)
-programlisting>
+screen>
preferred type
for strings, text, is used as the specific
type to resolve the unknown literals to.
-sect3>
+example>
-<sect3>
-
Factorial
+<example>
+
Factorial Operator Type Resolution
This example illustrates an interesting result. Traditionally, the
-factorial operator is defined for integers only. The
Postgres
+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,
Postgres
+If given a non-integer numeric argument,
PostgreSQL
will try to convert that argument to an integer for evaluation of the
factorial.
-<programlisting>
+<screen>
tgl=> select (4.3 !);
?column?
----------
24
(1 row)
-programlisting>
+screen>
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,
Postgres
+factorial of a floating point number,
PostgreSQL
will try to oblige.
-sect3>
-
+example>
+
Functions
+ The argument types of function calls are resolved according to the
+ following steps.
+
+
-
Function Call Type Resolution
+
Function Argument Type Resolution
-
-
Examples
+Examples
-<sect3>
-
Factorial Function
+<example>
+
Factorial Function Argument Type Resolution
There is only one factorial function defined in the pg_proc catalog.
So the following query automatically converts the int2 argument
to int4:
-<programlisting>
+<screen>
tgl=> select int4fac(int2 '4');
int4fac
---------
24
(1 row)
-programlisting>
+screen>
and is actually transformed by the parser to
-<programlisting>
+<screen>
tgl=> select int4fac(int4(int2 '4'));
int4fac
---------
24
(1 row)
-programlisting>
+screen>
-sect3>
+example>
-<sect3>
-
Substring Function
+<example>
+
Substring Function Type Resolution
There are two substr functions declared in pg_proc. However,
If called with a string constant of unspecified type, the type is matched up
directly with the only candidate function type:
-<programlisting>
+<screen>
tgl=> select substr('1234', 3);
substr
--------
34
(1 row)
-programlisting>
+screen>
If the string is declared to be of type varchar, as might be the case
if it comes from a table, then the parser will try to coerce it to become text:
-<programlisting>
+<screen>
tgl=> select substr(varchar '1234', 3);
substr
--------
34
(1 row)
-programlisting>
+screen>
which is transformed by the parser to become
-<programlisting>
+<screen>
tgl=> select substr(text(varchar '1234'), 3);
substr
--------
34
(1 row)
-programlisting>
+screen>
Actually, the parser is aware that text and varchar
explicit type conversion call is really inserted in this case.
+
And, if the function is called with an int4, the parser will
try to convert that to text:
-<programlisting>
+<screen>
tgl=> select substr(1234, 3);
substr
--------
34
(1 row)
-programlisting>
+screen>
actually executes as
-<programlisting>
+<screen>
tgl=> select substr(text(1234), 3);
substr
--------
34
(1 row)
-programlisting>
+screen>
This succeeds because there is a conversion function text(int4) in the
system catalog.
-sect3>
-
+example>
+
-
-
Examples
-
-
-
varchar Storage
+
+
varchar Storage Type Conversion
For a target column declared as varchar(4) the following query
ensures that the target is sized correctly:
-<programlisting>
+<screen>
tgl=> CREATE TABLE vv (v varchar(4));
CREATE
tgl=> INSERT INTO vv SELECT 'abc' || 'def';
------
abcd
(1 row)
-programlisting>
+screen>
-What's 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
+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
+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,int4) is found in the system
+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.
-
-
+
-
UNION and CASE Constructs
+
UNION> and CASE> Constructs
-The UNION and CASE constructs must match up possibly dissimilar types to
+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
+each output column of a union. CASE> uses the identical algorithm to match
up its result expressions.
-
UNION and CASE Type Resolution
+
UNION> and CASE> Type Resolution
-
-
Examples
+Examples
-<sect3>
-
Underspecified Types
+<example>
+
Underspecified Types in a Union
-<programlisting>
+<screen>
tgl=> SELECT text 'a' AS "Text" UNION SELECT 'b';
Text
------
a
b
(2 rows)
-programlisting>
+screen>
Here, the unknown-type literal 'b' will be resolved as type text.
-sect3>
+example>
-<sect3>
-
Simple UNION
+<example>
+
Type Conversion in a Simple Union
-<programlisting>
+<screen>
tgl=> SELECT 1.2 AS "Double" UNION SELECT 1;
Double
--------
1
1.2
(2 rows)
-programlisting>
+screen>
-sect3>
+example>
-<sect3>
-
Transposed UNION
+<example>
+
Type Conversion in a Transposed Union
Here the output type of the union is forced to match the type of
the first/top clause in the union:
-<programlisting>
+<screen>
tgl=> SELECT 1 AS "All integers"
tgl-> UNION SELECT CAST('2.2' AS REAL);
All integers
1
2
(2 rows)
-programlisting>
+screen>
Since REAL is not a preferred type, the parser sees no reason
falls back on the use-the-first-alternative rule.
This example demonstrates that the preferred-type mechanism doesn't encode
as much information as we'd like. Future versions of
-
Postgres may support a more general notion of
+
PostgreSQL may support a more general notion of
type preferences.
-sect3>
-
+example>
+