Markup examples as examples. Fix formatting of examples.

This commit is contained in:
Peter Eisentraut 2001-09-15 00:48:59 +00:00
parent 184c4afcd6
commit 4284002d35
3 changed files with 170 additions and 125 deletions

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/doc/src/sgml/stylesheet.css,v 1.1 2001/09/14 20:37:55 petere Exp $ */ /* $Header: /cvsroot/pgsql/doc/src/sgml/stylesheet.css,v 1.2 2001/09/15 00:48:59 petere Exp $ */
/* color scheme similar to www.postgresql.org */ /* color scheme similar to www.postgresql.org */
@ -38,6 +38,7 @@ DIV.example {
border-width: 0px; border-width: 0px;
border-left-width: 2px; border-left-width: 2px;
border-color: black; border-color: black;
margin: 0.5ex;
} }
/* less dense spacing of TOC */ /* less dense spacing of TOC */

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/stylesheet.dsl,v 1.9 2001/09/14 20:37:55 petere Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/stylesheet.dsl,v 1.10 2001/09/15 00:48:59 petere Exp $ -->
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [ <!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!-- must turn on one of these with -i on the jade command line --> <!-- must turn on one of these with -i on the jade command line -->
@ -68,6 +68,42 @@
(define html-index #t) (define html-index #t)
;; Block elements are allowed in PARA in DocBook, but not in P in
;; HTML. With %fix-para-wrappers% turned on, the stylesheets attempt
;; to avoid putting block elements in HTML P tags by outputting
;; additional end/begin P pairs around them.
(define %fix-para-wrappers% #t)
;; ...but we need to do some extra work to make the above apply to PRE
;; as well. (mostly pasted from dbverb.dsl)
(define ($verbatim-display$ indent line-numbers?)
(let ((content (make element gi: "PRE"
attributes: (list
(list "CLASS" (gi)))
(if (or indent line-numbers?)
($verbatim-line-by-line$ indent line-numbers?)
(process-children)))))
(if %shade-verbatim%
(make element gi: "TABLE"
attributes: ($shade-verbatim-attr$)
(make element gi: "TR"
(make element gi: "TD"
content)))
(make sequence
(para-check)
content
(para-check 'restart)))))
;; ...and for notes.
(element note
(make sequence
(para-check)
($admonition$)
(para-check 'restart)))
;;; XXX The above is very ugly. It might be better to run 'tidy' on
;;; the resulting *.html files.
]]> <!-- %output-html --> ]]> <!-- %output-html -->
<![ %output-print; [ <![ %output-print; [

View File

@ -1,34 +1,38 @@
<chapter Id="typeconv"> <chapter Id="typeconv">
<title>Type Conversion</title> <title>Type Conversion</title>
<sect1 id="typeconv-intro">
<title>Introduction</title>
<para> <para>
<acronym>SQL</acronym> queries can, intentionally or not, require <acronym>SQL</acronym> queries can, intentionally or not, require
mixing of different data types in the same expression. mixing of different data types in the same expression.
<productname>Postgres</productname> has extensive facilities for <productname>PostgreSQL</productname> has extensive facilities for
evaluating mixed-type expressions. evaluating mixed-type expressions.
</para> </para>
<para> <para>
In many cases a user will not need In many cases a user will not need
to understand the details of the type conversion mechanism. to understand the details of the type conversion mechanism.
However, the implicit conversions done by <productname>Postgres</productname> However, the implicit conversions done by <productname>PostgreSQL</productname>
can affect the results of a query. When necessary, these results can affect the results of a query. When necessary, these results
can be tailored by a user or programmer can be tailored by a user or programmer
using <emphasis>explicit</emphasis> type coercion. using <emphasis>explicit</emphasis> type coercion.
</para> </para>
<para> <para>
This chapter introduces the <productname>Postgres</productname> This chapter introduces the <productname>PostgreSQL</productname>
type conversion mechanisms and conventions. type conversion mechanisms and conventions.
Refer to the relevant sections in the User's Guide and Programmer's Guide Refer to the relevant sections in the <xref linkend="datatype"> and <xref linkend="functions">
for more information on specific data types and allowed functions and for more information on specific data types and allowed functions and
operators. operators.
</para> </para>
<para> <para>
The Programmer's Guide has more details on the exact algorithms used for The <citetitle>Programmer's Guide</citetitle> has more details on the exact algorithms used for
implicit type conversion and coercion. implicit type conversion and coercion.
</para> </para>
</sect1>
<sect1 id="typeconv-overview"> <sect1 id="typeconv-overview">
<title>Overview</title> <title>Overview</title>
@ -36,29 +40,29 @@ implicit type conversion and coercion.
<para> <para>
<acronym>SQL</acronym> is a strongly typed language. That is, every data item <acronym>SQL</acronym> is a strongly typed language. That is, every data item
has an associated data type which determines its behavior and allowed usage. has an associated data type which determines its behavior and allowed usage.
<productname>Postgres</productname> has an extensible type system that is <productname>PostgreSQL</productname> has an extensible type system that is
much more general and flexible than other <acronym>RDBMS</acronym> implementations. much more general and flexible than other <acronym>RDBMS</acronym> implementations.
Hence, most type conversion behavior in <productname>Postgres</productname> Hence, most type conversion behavior in <productname>PostgreSQL</productname>
should be governed by general rules rather than by ad-hoc heuristics to allow should be governed by general rules rather than by ad-hoc heuristics to allow
mixed-type expressions to be meaningful, even with user-defined types. mixed-type expressions to be meaningful, even with user-defined types.
</para> </para>
<para> <para>
The <productname>Postgres</productname> scanner/parser decodes lexical The <productname>PostgreSQL</productname> scanner/parser decodes lexical
elements into only five fundamental categories: integers, floats, strings, elements into only five fundamental categories: integers, floats, strings,
names, and keywords. Most extended types are first tokenized into names, and keywords. Most extended types are first tokenized into
strings. The <acronym>SQL</acronym> language definition allows specifying type strings. The <acronym>SQL</acronym> language definition allows specifying type
names with strings, and this mechanism can be used in names with strings, and this mechanism can be used in
<productname>Postgres</productname> to start the parser down the correct <productname>PostgreSQL</productname> to start the parser down the correct
path. For example, the query path. For example, the query
<programlisting> <screen>
tgl=> SELECT text 'Origin' AS "Label", point '(0,0)' AS "Value"; tgl=> SELECT text 'Origin' AS "Label", point '(0,0)' AS "Value";
Label | Value Label | Value
--------+------- --------+-------
Origin | (0,0) Origin | (0,0)
(1 row) (1 row)
</programlisting> </screen>
has two strings, of type <type>text</type> and <type>point</type>. has two strings, of type <type>text</type> and <type>point</type>.
If a type is not specified for a string, then the placeholder type If a type is not specified for a string, then the placeholder type
@ -68,7 +72,7 @@ stages as described below.
<para> <para>
There are four fundamental <acronym>SQL</acronym> constructs requiring There are four fundamental <acronym>SQL</acronym> constructs requiring
distinct type conversion rules in the <productname>Postgres</productname> distinct type conversion rules in the <productname>PostgreSQL</productname>
parser: parser:
</para> </para>
@ -79,8 +83,8 @@ Operators
</term> </term>
<listitem> <listitem>
<para> <para>
<productname>Postgres</productname> allows expressions with <productname>PostgreSQL</productname> allows expressions with
left- and right-unary (one argument) operators, prefix and postfix unary (one argument) operators,
as well as binary (two argument) operators. as well as binary (two argument) operators.
</para> </para>
</listitem> </listitem>
@ -91,12 +95,12 @@ Function calls
</term> </term>
<listitem> <listitem>
<para> <para>
Much of the <productname>Postgres</productname> type system is built around a Much of the <productname>PostgreSQL</productname> type system is built around a
rich set of functions. Function calls have one or more arguments which, for rich set of functions. Function calls have one or more arguments which, for
any specific query, must be matched to the functions available in the system any specific query, must be matched to the functions available in the system
catalog. Since <productname>Postgres</productname> permits function catalog. Since <productname>PostgreSQL</productname> permits function
overloading, the function name alone does not uniquely identify the function overloading, the function name alone does not uniquely identify the function
to be called --- the parser must select the right function based on the data to be called; the parser must select the right function based on the data
types of the supplied arguments. types of the supplied arguments.
</para> </para>
</listitem> </listitem>
@ -107,7 +111,7 @@ Query targets
</term> </term>
<listitem> <listitem>
<para> <para>
<acronym>SQL</acronym> INSERT and UPDATE statements place the results of <acronym>SQL</acronym> <command>INSERT</command> and <command>UPDATE</command> statements place the results of
expressions into a table. The expressions in the query must be matched up expressions into a table. The expressions in the query must be matched up
with, and perhaps converted to, the types of the target columns. with, and perhaps converted to, the types of the target columns.
</para> </para>
@ -115,15 +119,15 @@ with, and perhaps converted to, the types of the target columns.
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
UNION and CASE constructs <literal>UNION</literal> and <literal>CASE</literal> constructs
</term> </term>
<listitem> <listitem>
<para> <para>
Since all select results from a UNION SELECT statement must appear in a single Since all select results from a unionized <literal>SELECT</literal> statement must appear in a single
set of columns, the types of the results set of columns, the types of the results
of each SELECT clause must be matched up and converted to a uniform set. of each <literal>SELECT</> clause must be matched up and converted to a uniform set.
Similarly, the result expressions of a CASE construct must be coerced to Similarly, the result expressions of a <literal>CASE</> construct must be coerced to
a common type so that the CASE expression as a whole has a known output type. a common type so that the <literal>CASE</> expression as a whole has a known output type.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -131,14 +135,14 @@ a common type so that the CASE expression as a whole has a known output type.
<para> <para>
Many of the general type conversion rules use simple conventions built on Many of the general type conversion rules use simple conventions built on
the <productname>Postgres</productname> function and operator system tables. the <productname>PostgreSQL</productname> function and operator system tables.
There are some heuristics included in the conversion rules to better support There are some heuristics included in the conversion rules to better support
conventions for the <acronym>SQL92</acronym> standard native types such as conventions for the <acronym>SQL</acronym> standard native types such as
<type>smallint</type>, <type>integer</type>, and <type>float</type>. <type>smallint</type>, <type>integer</type>, and <type>real</type>.
</para> </para>
<para> <para>
The <productname>Postgres</productname> parser uses the convention that all The <productname>PostgreSQL</productname> parser uses the convention that all
type conversion functions take a single argument of the source type and are type conversion functions take a single argument of the source type and are
named with the same name as the target type. Any function meeting these named with the same name as the target type. Any function meeting these
criteria is considered to be a valid conversion function, and may be used criteria is considered to be a valid conversion function, and may be used
@ -162,9 +166,6 @@ they will raise an error when there are multiple choices for user-defined
types. types.
</para> </para>
<sect2>
<title>Guidelines</title>
<para> <para>
All type conversion rules are designed with several principles in mind: All type conversion rules are designed with several principles in mind:
@ -185,7 +186,7 @@ be converted to a user-defined type (of course, only if conversion is necessary)
<listitem> <listitem>
<para> <para>
User-defined types are not related. Currently, <productname>Postgres</productname> User-defined types are not related. Currently, <productname>PostgreSQL</productname>
does not have information available to it on relationships between types, other than does not have information available to it on relationships between types, other than
hardcoded heuristics for built-in types and implicit relationships based on available functions hardcoded heuristics for built-in types and implicit relationships based on available functions
in the catalog. in the catalog.
@ -209,18 +210,25 @@ should use this new function and will no longer do the implicit conversion using
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
</sect2>
</sect1> </sect1>
<sect1 id="typeconv-oper"> <sect1 id="typeconv-oper">
<title>Operators</title> <title>Operators</title>
<para>
The operand types of an operator invocation are resolved following
to the procedure below. Note that this procedure is indirectly affected
by the precedence of the involved operators. See <xref
linkend="sql-precedence"> for more information.
</para>
<procedure> <procedure>
<title>Operator Type Resolution</title> <title>Operand Type Resolution</title>
<step performance="required"> <step performance="required">
<para> <para>
Check for an exact match in the pg_operator system catalog. Check for an exact match in the <classname>pg_operator</classname> system catalog.
</para> </para>
<substeps> <substeps>
@ -299,46 +307,45 @@ then fail.
</step> </step>
</procedure> </procedure>
<sect2> <bridgehead renderas="sect2">Examples</bridgehead>
<title>Examples</title>
<sect3> <example>
<title>Exponentiation Operator</title> <title>Exponentiation Operator Type Resolution</title>
<para> <para>
There is only one exponentiation There is only one exponentiation
operator defined in the catalog, and it takes arguments of type operator defined in the catalog, and it takes arguments of type
<type>double precision</type>. <type>double precision</type>.
The scanner assigns an initial type of <type>int4</type> to both arguments The scanner assigns an initial type of <type>integer</type> to both arguments
of this query expression: of this query expression:
<programlisting> <screen>
tgl=> select 2 ^ 3 AS "Exp"; tgl=> select 2 ^ 3 AS "Exp";
Exp Exp
----- -----
8 8
(1 row) (1 row)
</programlisting> </screen>
So the parser does a type conversion on both operands and the query So the parser does a type conversion on both operands and the query
is equivalent to is equivalent to
<programlisting> <screen>
tgl=> select CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp"; tgl=> select CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp";
Exp Exp
----- -----
8 8
(1 row) (1 row)
</programlisting> </screen>
or or
<programlisting> <screen>
tgl=> select 2.0 ^ 3.0 AS "Exp"; tgl=> select 2.0 ^ 3.0 AS "Exp";
Exp Exp
----- -----
8 8
(1 row) (1 row)
</programlisting> </screen>
<note> <note>
<para> <para>
@ -348,10 +355,10 @@ have an impact on the performance of queries involving large tables.
</para> </para>
</note> </note>
</para> </para>
</sect3> </example>
<sect3> <example>
<title>String Concatenation</title> <title>String Concatenation Operator Type Resolution</title>
<para> <para>
A string-like syntax is used for working with string types as well as for A string-like syntax is used for working with string types as well as for
@ -361,13 +368,13 @@ Strings with unspecified type are matched with likely operator candidates.
<para> <para>
One unspecified argument: One unspecified argument:
<programlisting> <screen>
tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown"; tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
Text and Unknown Text and Unknown
------------------ ------------------
abcdef abcdef
(1 row) (1 row)
</programlisting> </screen>
</para> </para>
<para> <para>
@ -378,13 +385,13 @@ be interpreted as of type <type>text</type>.
<para> <para>
Concatenation on unspecified types: Concatenation on unspecified types:
<programlisting> <screen>
tgl=> SELECT 'abc' || 'def' AS "Unspecified"; tgl=> SELECT 'abc' || 'def' AS "Unspecified";
Unspecified Unspecified
------------- -------------
abcdef abcdef
(1 row) (1 row)
</programlisting> </screen>
</para> </para>
<para> <para>
@ -396,26 +403,26 @@ that category is selected, and then the
<quote>preferred type</quote> for strings, <type>text</type>, is used as the specific <quote>preferred type</quote> for strings, <type>text</type>, is used as the specific
type to resolve the unknown literals to. type to resolve the unknown literals to.
</para> </para>
</sect3> </example>
<sect3> <example>
<title>Factorial</title> <title>Factorial Operator Type Resolution</title>
<para> <para>
This example illustrates an interesting result. Traditionally, the This example illustrates an interesting result. Traditionally, the
factorial operator is defined for integers only. The <productname>Postgres</productname> factorial operator is defined for integers only. The <productname>PostgreSQL</productname>
operator catalog has only one entry for factorial, taking an integer operand. operator catalog has only one entry for factorial, taking an integer operand.
If given a non-integer numeric argument, <productname>Postgres</productname> If given a non-integer numeric argument, <productname>PostgreSQL</productname>
will try to convert that argument to an integer for evaluation of the will try to convert that argument to an integer for evaluation of the
factorial. factorial.
<programlisting> <screen>
tgl=> select (4.3 !); tgl=> select (4.3 !);
?column? ?column?
---------- ----------
24 24
(1 row) (1 row)
</programlisting> </screen>
<note> <note>
<para> <para>
@ -423,20 +430,25 @@ Of course, this leads to a mathematically suspect result,
since in principle the factorial of a non-integer is not defined. since in principle the factorial of a non-integer is not defined.
However, the role of a database is not to teach mathematics, but 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 to be a tool for data manipulation. If a user chooses to take the
factorial of a floating point number, <productname>Postgres</productname> factorial of a floating point number, <productname>PostgreSQL</productname>
will try to oblige. will try to oblige.
</para> </para>
</note> </note>
</para> </para>
</sect3> </example>
</sect2>
</sect1> </sect1>
<sect1 id="typeconv-func"> <sect1 id="typeconv-func">
<title>Functions</title> <title>Functions</title>
<para>
The argument types of function calls are resolved according to the
following steps.
</para>
<procedure> <procedure>
<title>Function Call Type Resolution</title> <title>Function Argument Type Resolution</title>
<step performance="required"> <step performance="required">
<para> <para>
@ -520,38 +532,37 @@ to the named data type.
</step> </step>
</procedure> </procedure>
<sect2> <bridgehead renderas="sect2">Examples</bridgehead>
<title>Examples</title>
<sect3> <example>
<title>Factorial Function</title> <title>Factorial Function Argument Type Resolution</title>
<para> <para>
There is only one factorial function defined in the <classname>pg_proc</classname> catalog. There is only one factorial function defined in the <classname>pg_proc</classname> catalog.
So the following query automatically converts the <type>int2</type> argument So the following query automatically converts the <type>int2</type> argument
to <type>int4</type>: to <type>int4</type>:
<programlisting> <screen>
tgl=> select int4fac(int2 '4'); tgl=> select int4fac(int2 '4');
int4fac int4fac
--------- ---------
24 24
(1 row) (1 row)
</programlisting> </screen>
and is actually transformed by the parser to and is actually transformed by the parser to
<programlisting> <screen>
tgl=> select int4fac(int4(int2 '4')); tgl=> select int4fac(int4(int2 '4'));
int4fac int4fac
--------- ---------
24 24
(1 row) (1 row)
</programlisting> </screen>
</para> </para>
</sect3> </example>
<sect3> <example>
<title>Substring Function</title> <title>Substring Function Type Resolution</title>
<para> <para>
There are two <function>substr</function> functions declared in <classname>pg_proc</classname>. However, There are two <function>substr</function> functions declared in <classname>pg_proc</classname>. However,
@ -561,34 +572,35 @@ only one takes two arguments, of types <type>text</type> and <type>int4</type>.
<para> <para>
If called with a string constant of unspecified type, the type is matched up If called with a string constant of unspecified type, the type is matched up
directly with the only candidate function type: directly with the only candidate function type:
<programlisting> <screen>
tgl=> select substr('1234', 3); tgl=> select substr('1234', 3);
substr substr
-------- --------
34 34
(1 row) (1 row)
</programlisting> </screen>
</para> </para>
<para> <para>
If the string is declared to be of type <type>varchar</type>, as might be the case If the string is declared to be of type <type>varchar</type>, as might be the case
if it comes from a table, then the parser will try to coerce it to become <type>text</type>: if it comes from a table, then the parser will try to coerce it to become <type>text</type>:
<programlisting> <screen>
tgl=> select substr(varchar '1234', 3); tgl=> select substr(varchar '1234', 3);
substr substr
-------- --------
34 34
(1 row) (1 row)
</programlisting> </screen>
which is transformed by the parser to become which is transformed by the parser to become
<programlisting> <screen>
tgl=> select substr(text(varchar '1234'), 3); tgl=> select substr(text(varchar '1234'), 3);
substr substr
-------- --------
34 34
(1 row) (1 row)
</programlisting> </screen>
</para> </para>
<para>
<note> <note>
<para> <para>
Actually, the parser is aware that <type>text</type> and <type>varchar</type> Actually, the parser is aware that <type>text</type> and <type>varchar</type>
@ -597,30 +609,31 @@ accepts the other without doing any physical conversion. Therefore, no
explicit type conversion call is really inserted in this case. explicit type conversion call is really inserted in this case.
</para> </para>
</note> </note>
</para>
<para> <para>
And, if the function is called with an <type>int4</type>, the parser will And, if the function is called with an <type>int4</type>, the parser will
try to convert that to <type>text</type>: try to convert that to <type>text</type>:
<programlisting> <screen>
tgl=> select substr(1234, 3); tgl=> select substr(1234, 3);
substr substr
-------- --------
34 34
(1 row) (1 row)
</programlisting> </screen>
actually executes as actually executes as
<programlisting> <screen>
tgl=> select substr(text(1234), 3); tgl=> select substr(text(1234), 3);
substr substr
-------- --------
34 34
(1 row) (1 row)
</programlisting> </screen>
This succeeds because there is a conversion function text(int4) in the This succeeds because there is a conversion function text(int4) in the
system catalog. system catalog.
</para> </para>
</sect3> </example>
</sect2>
</sect1> </sect1>
<sect1 id="typeconv-query"> <sect1 id="typeconv-query">
@ -654,17 +667,14 @@ passing the column's declared length as the second parameter.
</procedure> </procedure>
<sect2> <example>
<title>Examples</title> <title><type>varchar</type> Storage Type Conversion</title>
<sect3>
<title><type>varchar</type> Storage</title>
<para> <para>
For a target column declared as <type>varchar(4)</type> the following query For a target column declared as <type>varchar(4)</type> the following query
ensures that the target is sized correctly: ensures that the target is sized correctly:
<programlisting> <screen>
tgl=> CREATE TABLE vv (v varchar(4)); tgl=> CREATE TABLE vv (v varchar(4));
CREATE CREATE
tgl=> INSERT INTO vv SELECT 'abc' || 'def'; tgl=> INSERT INTO vv SELECT 'abc' || 'def';
@ -674,33 +684,32 @@ tgl=> SELECT * FROM vv;
------ ------
abcd abcd
(1 row) (1 row)
</programlisting> </screen>
What's really happened here is that the two unknown literals are resolved What has really happened here is that the two unknown literals are resolved
to text by default, allowing the <literal>||</literal> operator to be to <type>text</type> by default, allowing the <literal>||</literal> operator to be
resolved as text concatenation. Then the text result of the operator resolved as <type>text</type> concatenation. Then the <type>text</type> result of the operator
is coerced to <type>varchar</type> to match the target column type. (But, since the is coerced to <type>varchar</type> to match the target column type. (But, since the
parser knows that text and <type>varchar</type> are binary-compatible, this coercion parser knows that <type>text</type> and <type>varchar</type> are binary-compatible, this coercion
is implicit and does not insert any real function call.) Finally, the is implicit and does not insert any real function call.) Finally, the
sizing function <literal>varchar(varchar,int4)</literal> is found in the system sizing function <literal>varchar(varchar, integer)</literal> is found in the system
catalogs and applied to the operator's result and the stored column length. catalogs and applied to the operator's result and the stored column length.
This type-specific function performs the desired truncation. This type-specific function performs the desired truncation.
</para> </para>
</sect3> </example>
</sect2>
</sect1> </sect1>
<sect1 id="typeconv-union-case"> <sect1 id="typeconv-union-case">
<title>UNION and CASE Constructs</title> <title><literal>UNION</> and <literal>CASE</> Constructs</title>
<para> <para>
The UNION and CASE constructs must match up possibly dissimilar types to The <literal>UNION</> and <literal>CASE</> constructs must match up possibly dissimilar types to
become a single result set. The resolution algorithm is applied separately 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. <literal>CASE</> uses the identical algorithm to match
up its result expressions. up its result expressions.
</para> </para>
<procedure> <procedure>
<title>UNION and CASE Type Resolution</title> <title><literal>UNION</> and <literal>CASE</> Type Resolution</title>
<step performance="required"> <step performance="required">
<para> <para>
@ -731,48 +740,47 @@ Coerce all inputs to the selected type.
</para></step> </para></step>
</procedure> </procedure>
<sect2> <bridgehead renderas="sect2">Examples</bridgehead>
<title>Examples</title>
<sect3> <example>
<title>Underspecified Types</title> <title>Underspecified Types in a Union</title>
<para> <para>
<programlisting> <screen>
tgl=> SELECT text 'a' AS "Text" UNION SELECT 'b'; tgl=> SELECT text 'a' AS "Text" UNION SELECT 'b';
Text Text
------ ------
a a
b b
(2 rows) (2 rows)
</programlisting> </screen>
Here, the unknown-type literal <literal>'b'</literal> will be resolved as type text. Here, the unknown-type literal <literal>'b'</literal> will be resolved as type text.
</para> </para>
</sect3> </example>
<sect3> <example>
<title>Simple UNION</title> <title>Type Conversion in a Simple Union</title>
<para> <para>
<programlisting> <screen>
tgl=> SELECT 1.2 AS "Double" UNION SELECT 1; tgl=> SELECT 1.2 AS "Double" UNION SELECT 1;
Double Double
-------- --------
1 1
1.2 1.2
(2 rows) (2 rows)
</programlisting> </screen>
</para> </para>
</sect3> </example>
<sect3> <example>
<title>Transposed UNION</title> <title>Type Conversion in a Transposed Union</title>
<para> <para>
Here the output type of the union is forced to match the type of Here the output type of the union is forced to match the type of
the first/top clause in the union: the first/top clause in the union:
<programlisting> <screen>
tgl=> SELECT 1 AS "All integers" tgl=> SELECT 1 AS "All integers"
tgl-> UNION SELECT CAST('2.2' AS REAL); tgl-> UNION SELECT CAST('2.2' AS REAL);
All integers All integers
@ -780,7 +788,7 @@ tgl-> UNION SELECT CAST('2.2' AS REAL);
1 1
2 2
(2 rows) (2 rows)
</programlisting> </screen>
</para> </para>
<para> <para>
Since <type>REAL</type> is not a preferred type, the parser sees no reason Since <type>REAL</type> is not a preferred type, the parser sees no reason
@ -788,11 +796,11 @@ to select it over <type>INTEGER</type> (which is what the 1 is), and instead
falls back on the use-the-first-alternative rule. falls back on the use-the-first-alternative rule.
This example demonstrates that the preferred-type mechanism doesn't encode This example demonstrates that the preferred-type mechanism doesn't encode
as much information as we'd like. Future versions of as much information as we'd like. Future versions of
<productname>Postgres</productname> may support a more general notion of <productname>PostgreSQL</productname> may support a more general notion of
type preferences. type preferences.
</para> </para>
</sect3> </example>
</sect2>
</sect1> </sect1>
</chapter> </chapter>