2003-03-13 02:30:29 +01:00
|
|
|
<!--
|
2003-09-13 00:17:24 +02:00
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/typeconv.sgml,v 1.34 2003/09/12 22:17:24 tgl Exp $
|
2003-03-13 02:30:29 +01:00
|
|
|
-->
|
|
|
|
|
1998-07-29 08:50:04 +02:00
|
|
|
<chapter Id="typeconv">
|
1998-07-08 15:53:15 +02:00
|
|
|
<title>Type Conversion</title>
|
|
|
|
|
2003-08-31 19:32:24 +02:00
|
|
|
<indexterm zone="typeconv">
|
|
|
|
<primary>data type</primary>
|
|
|
|
<secondary>conversion</secondary>
|
|
|
|
</indexterm>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
<acronym>SQL</acronym> statements can, intentionally or not, require
|
1998-07-08 15:53:15 +02:00
|
|
|
mixing of different data types in the same expression.
|
2001-09-15 02:48:59 +02:00
|
|
|
<productname>PostgreSQL</productname> has extensive facilities for
|
1998-07-08 15:53:15 +02:00
|
|
|
evaluating mixed-type expressions.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
In many cases a user will not need
|
|
|
|
to understand the details of the type conversion mechanism.
|
2001-09-15 02:48:59 +02:00
|
|
|
However, the implicit conversions done by <productname>PostgreSQL</productname>
|
2000-12-17 06:55:26 +01:00
|
|
|
can affect the results of a query. When necessary, these results
|
1998-07-08 15:53:15 +02:00
|
|
|
can be tailored by a user or programmer
|
2003-03-13 02:30:29 +01:00
|
|
|
using <emphasis>explicit</emphasis> type conversion.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
This chapter introduces the <productname>PostgreSQL</productname>
|
2000-12-17 06:55:26 +01:00
|
|
|
type conversion mechanisms and conventions.
|
2001-10-15 03:00:59 +02:00
|
|
|
Refer to the relevant sections in <xref linkend="datatype"> and <xref linkend="functions">
|
2000-12-17 06:55:26 +01:00
|
|
|
for more information on specific data types and allowed functions and
|
|
|
|
operators.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="typeconv-overview">
|
1998-07-08 15:53:15 +02:00
|
|
|
<title>Overview</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
<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.
|
2001-09-15 02:48:59 +02:00
|
|
|
<productname>PostgreSQL</productname> has an extensible type system that is
|
2002-11-11 21:14:04 +01:00
|
|
|
much more general and flexible than other <acronym>SQL</acronym> implementations.
|
2001-09-15 02:48:59 +02:00
|
|
|
Hence, most type conversion behavior in <productname>PostgreSQL</productname>
|
2002-01-20 23:19:57 +01:00
|
|
|
should be governed by general rules rather than by <foreignphrase>ad hoc</> heuristics, to allow
|
2001-10-15 03:00:59 +02:00
|
|
|
mixed-type expressions to be meaningful even with user-defined types.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
The <productname>PostgreSQL</productname> scanner/parser decodes lexical
|
2001-11-28 21:49:10 +01:00
|
|
|
elements into only five fundamental categories: integers, floating-point numbers, strings,
|
2003-05-26 02:11:29 +02:00
|
|
|
names, and key words. Constants of most non-numeric types are first classified as
|
2000-12-17 06:55:26 +01:00
|
|
|
strings. The <acronym>SQL</acronym> language definition allows specifying type
|
|
|
|
names with strings, and this mechanism can be used in
|
2001-09-15 02:48:59 +02:00
|
|
|
<productname>PostgreSQL</productname> to start the parser down the correct
|
2000-12-17 06:55:26 +01:00
|
|
|
path. For example, the query
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT text 'Origin' AS "label", point '(0,0)' AS "value";
|
|
|
|
|
|
|
|
label | value
|
2000-03-26 20:32:30 +02:00
|
|
|
--------+-------
|
|
|
|
Origin | (0,0)
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-10-15 03:00:59 +02:00
|
|
|
has two literal constants, of type <type>text</type> and <type>point</type>.
|
|
|
|
If a type is not specified for a string literal, then the placeholder type
|
2003-03-13 02:30:29 +01:00
|
|
|
<type>unknown</type> is assigned initially, to be resolved in later
|
2000-12-17 06:55:26 +01:00
|
|
|
stages as described below.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
There are four fundamental <acronym>SQL</acronym> constructs requiring
|
2001-09-15 02:48:59 +02:00
|
|
|
distinct type conversion rules in the <productname>PostgreSQL</productname>
|
1998-07-08 15:53:15 +02:00
|
|
|
parser:
|
|
|
|
|
|
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
|
|
<term>
|
|
|
|
Operators
|
|
|
|
</term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
<productname>PostgreSQL</productname> allows expressions with
|
2001-11-28 21:49:10 +01:00
|
|
|
prefix and postfix unary (one-argument) operators,
|
|
|
|
as well as binary (two-argument) operators.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>
|
|
|
|
Function calls
|
|
|
|
</term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
Much of the <productname>PostgreSQL</productname> type system is built around a
|
2003-03-13 02:30:29 +01:00
|
|
|
rich set of functions. Function calls can have one or more arguments.
|
|
|
|
Since <productname>PostgreSQL</productname> permits function
|
2000-12-17 06:55:26 +01:00
|
|
|
overloading, the function name alone does not uniquely identify the function
|
2001-09-15 02:48:59 +02:00
|
|
|
to be called; the parser must select the right function based on the data
|
2000-12-17 06:55:26 +01:00
|
|
|
types of the supplied arguments.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>
|
2003-03-13 02:30:29 +01:00
|
|
|
Value Storage
|
1998-07-08 15:53:15 +02:00
|
|
|
</term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
<acronym>SQL</acronym> <command>INSERT</command> and <command>UPDATE</command> statements place the results of
|
2003-03-13 02:30:29 +01:00
|
|
|
expressions into a table. The expressions in the statement must be matched up
|
2000-12-17 06:55:26 +01:00
|
|
|
with, and perhaps converted to, the types of the target columns.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>
|
2003-08-15 01:13:27 +02:00
|
|
|
<literal>UNION</literal>, <literal>CASE</literal>, and <literal>ARRAY</literal> constructs
|
1998-07-08 15:53:15 +02:00
|
|
|
</term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2003-08-15 01:13:27 +02:00
|
|
|
Since all query results from a unionized <literal>SELECT</literal> statement
|
|
|
|
must appear in a single set of columns, the types of the results of each
|
|
|
|
<literal>SELECT</> clause must be matched up and converted to a uniform set.
|
|
|
|
Similarly, the branch expressions of a <literal>CASE</> construct must be
|
|
|
|
converted to a common type so that the <literal>CASE</> expression as a whole
|
|
|
|
has a known output type. The same holds for <literal>ARRAY</> constructs.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2002-11-11 21:14:04 +01:00
|
|
|
The system catalogs store information about which conversions, called
|
|
|
|
<firstterm>casts</firstterm>, between data types are valid, and how to
|
|
|
|
perform those conversions. Additional casts can be added by the user
|
|
|
|
with the <command>CREATE CAST</command> command. (This is usually
|
|
|
|
done in conjunction with defining new data types. The set of casts
|
2003-05-26 02:11:29 +02:00
|
|
|
between the built-in types has been carefully crafted and is best not
|
|
|
|
altered.)
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2003-08-31 19:32:24 +02:00
|
|
|
<indexterm>
|
|
|
|
<primary>data type</primary>
|
|
|
|
<secondary>category</secondary>
|
|
|
|
</indexterm>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<para>
|
|
|
|
An additional heuristic is provided in the parser to allow better guesses
|
|
|
|
at proper behavior for <acronym>SQL</acronym> standard types. There are
|
2001-09-09 19:21:59 +02:00
|
|
|
several basic <firstterm>type categories</firstterm> defined: <type>boolean</type>,
|
|
|
|
<type>numeric</type>, <type>string</type>, <type>bitstring</type>, <type>datetime</type>, <type>timespan</type>, <type>geometric</type>, <type>network</type>,
|
1998-07-08 15:53:15 +02:00
|
|
|
and user-defined. Each category, with the exception of user-defined, has
|
2003-05-26 02:11:29 +02:00
|
|
|
one or more <firstterm>preferred types</firstterm> which are preferentially
|
|
|
|
selected when there is ambiguity.
|
2000-12-17 06:55:26 +01:00
|
|
|
In the user-defined category, each type is its own preferred type.
|
|
|
|
Ambiguous expressions (those with multiple candidate parsing solutions)
|
2003-03-13 02:30:29 +01:00
|
|
|
can therefore often be resolved when there are multiple possible built-in types, but
|
2000-12-17 06:55:26 +01:00
|
|
|
they will raise an error when there are multiple choices for user-defined
|
|
|
|
types.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
All type conversion rules are designed with several principles in mind:
|
|
|
|
|
2002-11-11 21:14:04 +01:00
|
|
|
<itemizedlist>
|
1998-07-08 15:53:15 +02:00
|
|
|
<listitem>
|
|
|
|
<para>
|
2000-03-20 05:22:11 +01:00
|
|
|
Implicit conversions should never have surprising or unpredictable outcomes.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2002-01-20 23:19:57 +01:00
|
|
|
User-defined types, of which the parser has no <foreignphrase>a priori</> knowledge, should be
|
2001-09-13 17:55:24 +02:00
|
|
|
<quote>higher</quote> in the type hierarchy. In mixed-type expressions, native types shall always
|
1998-07-08 15:53:15 +02:00
|
|
|
be converted to a user-defined type (of course, only if conversion is necessary).
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
User-defined types are not related. Currently, <productname>PostgreSQL</productname>
|
1998-07-08 15:53:15 +02:00
|
|
|
does not have information available to it on relationships between types, other than
|
2003-05-26 02:11:29 +02:00
|
|
|
hardcoded heuristics for built-in types and implicit relationships based on
|
|
|
|
available functions and casts.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
There should be no extra overhead from the parser or executor
|
|
|
|
if a query does not need implicit type conversion.
|
|
|
|
That is, if a query is well formulated and the types already match up, then the query should proceed
|
|
|
|
without spending extra time in the parser and without introducing unnecessary implicit conversion
|
2003-03-13 02:30:29 +01:00
|
|
|
calls into the query.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
Additionally, if a query usually requires an implicit conversion for a function, and
|
2003-03-13 02:30:29 +01:00
|
|
|
if then the user defines a new function with the correct argument types, the parser
|
1998-07-08 15:53:15 +02:00
|
|
|
should use this new function and will no longer do the implicit conversion using the old function.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
1998-07-08 15:53:15 +02:00
|
|
|
</itemizedlist>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
|
1998-12-29 03:24:47 +01:00
|
|
|
</sect1>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="typeconv-oper">
|
1998-07-08 15:53:15 +02:00
|
|
|
<title>Operators</title>
|
|
|
|
|
2003-08-31 19:32:24 +02:00
|
|
|
<indexterm zone="typeconv-oper">
|
|
|
|
<primary>operator</primary>
|
|
|
|
<secondary>type resolution in an invocation</secondary>
|
|
|
|
</indexterm>
|
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
The specific operator to be used in an operator invocation is determined
|
|
|
|
by following
|
2001-10-15 03:00:59 +02:00
|
|
|
the procedure below. Note that this procedure is indirectly affected
|
2001-09-15 02:48:59 +02:00
|
|
|
by the precedence of the involved operators. See <xref
|
|
|
|
linkend="sql-precedence"> for more information.
|
|
|
|
</para>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<procedure>
|
2003-05-26 02:11:29 +02:00
|
|
|
<title>Operator Type Resolution</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2002-04-25 22:14:43 +02:00
|
|
|
Select the operators to be considered from the
|
|
|
|
<classname>pg_operator</classname> system catalog. If an unqualified
|
2003-03-13 02:30:29 +01:00
|
|
|
operator name was used (the usual case), the operators
|
2002-04-25 22:14:43 +02:00
|
|
|
considered are those of the right name and argument count that are
|
2002-09-13 00:05:36 +02:00
|
|
|
visible in the current search path (see <xref linkend="ddl-schemas-path">).
|
2002-04-25 22:14:43 +02:00
|
|
|
If a qualified operator name was given, only operators in the specified
|
|
|
|
schema are considered.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<substeps>
|
|
|
|
<step performance="optional">
|
|
|
|
<para>
|
|
|
|
If the search path finds multiple operators of identical argument types,
|
|
|
|
only the one appearing earliest in the path is considered. But operators of
|
|
|
|
different argument types are considered on an equal footing regardless of
|
|
|
|
search path position.
|
|
|
|
</para>
|
|
|
|
</step>
|
|
|
|
</substeps>
|
|
|
|
</step>
|
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
|
|
|
Check for an operator accepting exactly the input argument types.
|
|
|
|
If one exists (there can be only one exact match in the set of
|
|
|
|
operators considered), use it.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<substeps>
|
|
|
|
<step performance="optional">
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
If one argument of a binary operator invocation is of the <type>unknown</type> type,
|
2000-12-17 06:55:26 +01:00
|
|
|
then assume it is the same type as the other argument for this check.
|
|
|
|
Other cases involving <type>unknown</type> will never find a match at
|
|
|
|
this step.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
</substeps>
|
1998-12-29 03:24:47 +01:00
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
|
|
|
Look for the best match.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
<substeps>
|
2000-12-17 06:55:26 +01:00
|
|
|
<step performance="required">
|
1998-07-08 15:53:15 +02:00
|
|
|
<para>
|
2002-04-25 22:14:43 +02:00
|
|
|
Discard candidate operators for which the input types do not match
|
2003-03-13 02:30:29 +01:00
|
|
|
and cannot be converted (using an implicit conversion) to match.
|
2002-04-25 22:14:43 +02:00
|
|
|
<type>unknown</type> literals are
|
2003-03-13 02:30:29 +01:00
|
|
|
assumed to be convertible to anything for this purpose. If only one
|
2002-04-25 22:14:43 +02:00
|
|
|
candidate remains, use it; else continue to the next step.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2000-12-17 06:55:26 +01:00
|
|
|
Run through all candidates and keep those with the most exact matches
|
2003-05-26 02:11:29 +02:00
|
|
|
on input types. (Domain types are considered the same as their base type
|
|
|
|
for this purpose.) Keep all candidates if none have any exact matches.
|
2000-12-17 06:55:26 +01:00
|
|
|
If only one candidate remains, use it; else continue to the next step.
|
|
|
|
</para>
|
2000-12-17 18:50:46 +01:00
|
|
|
</step>
|
2000-12-17 06:55:26 +01:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
Run through all candidates and keep those that accept preferred types (of the
|
|
|
|
input datatype's type category) at the most positions where type conversion
|
|
|
|
will be required.
|
2000-12-17 06:55:26 +01:00
|
|
|
Keep all candidates if none accept preferred types.
|
|
|
|
If only one candidate remains, use it; else continue to the next step.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
If any input arguments are <type>unknown</type>, check the type
|
2001-10-13 01:32:34 +02:00
|
|
|
categories accepted at those argument positions by the remaining
|
2003-05-26 02:11:29 +02:00
|
|
|
candidates. At each position, select the <type>string</type> category
|
|
|
|
if any
|
2003-03-13 02:30:29 +01:00
|
|
|
candidate accepts that category. (This bias towards string is appropriate
|
|
|
|
since an unknown-type literal does look like a string.) Otherwise, if
|
2001-10-13 01:32:34 +02:00
|
|
|
all the remaining candidates accept the same type category, select that
|
|
|
|
category; otherwise fail because the correct choice cannot be deduced
|
2003-05-26 02:11:29 +02:00
|
|
|
without more clues. Now discard
|
2003-03-13 02:30:29 +01:00
|
|
|
candidates that do not accept the selected type category. Furthermore,
|
2001-10-13 01:32:34 +02:00
|
|
|
if any candidate accepts a preferred type at a given argument position,
|
|
|
|
discard candidates that accept non-preferred types for that argument.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2000-12-17 06:55:26 +01:00
|
|
|
If only one candidate remains, use it. If no candidate or more than one
|
|
|
|
candidate remains,
|
2000-12-19 01:54:59 +01:00
|
|
|
then fail.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
</substeps>
|
1998-12-29 03:24:47 +01:00
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
</procedure>
|
|
|
|
|
2003-03-13 02:30:29 +01:00
|
|
|
<para>
|
|
|
|
Some examples follow.
|
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
|
|
|
<title>Exponentiation Operator Type Resolution</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
There is only one exponentiation
|
2001-01-20 21:59:29 +01:00
|
|
|
operator defined in the catalog, and it takes arguments of type
|
|
|
|
<type>double precision</type>.
|
2001-09-15 02:48:59 +02:00
|
|
|
The scanner assigns an initial type of <type>integer</type> to both arguments
|
1998-07-08 15:53:15 +02:00
|
|
|
of this query expression:
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT 2 ^ 3 AS "exp";
|
|
|
|
|
|
|
|
exp
|
2000-03-26 20:32:30 +02:00
|
|
|
-----
|
|
|
|
8
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
So the parser does a type conversion on both operands and the query
|
|
|
|
is equivalent to
|
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "exp";
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
|
|
|
<title>String Concatenation Operator Type Resolution</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
A string-like syntax is used for working with string types as well as for
|
2003-03-13 02:30:29 +01:00
|
|
|
working with complex extension types.
|
1998-07-08 15:53:15 +02:00
|
|
|
Strings with unspecified type are matched with likely operator candidates.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-10-15 03:00:59 +02:00
|
|
|
An example with one unspecified argument:
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT text 'abc' || 'def' AS "text and unknown";
|
|
|
|
|
|
|
|
text and unknown
|
2000-03-26 20:32:30 +02:00
|
|
|
------------------
|
|
|
|
abcdef
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
In this case the parser looks to see if there is an operator taking <type>text</type>
|
|
|
|
for both arguments. Since there is, it assumes that the second argument should
|
|
|
|
be interpreted as of type <type>text</type>.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
Here is a concatenation on unspecified types:
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT 'abc' || 'def' AS "unspecified";
|
|
|
|
|
|
|
|
unspecified
|
2000-03-26 20:32:30 +02:00
|
|
|
-------------
|
|
|
|
abcdef
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
In this case there is no initial hint for which type to use, since no types
|
|
|
|
are specified in the query. So, the parser looks for all candidate operators
|
2000-12-17 06:55:26 +01:00
|
|
|
and finds that there are candidates accepting both string-category and
|
2001-09-09 19:21:59 +02:00
|
|
|
bit-string-category inputs. Since string category is preferred when available,
|
2000-12-17 06:55:26 +01:00
|
|
|
that category is selected, and then the
|
2003-03-13 02:30:29 +01:00
|
|
|
preferred type for strings, <type>text</type>, is used as the specific
|
2000-12-17 06:55:26 +01:00
|
|
|
type to resolve the unknown literals to.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2003-03-20 17:17:32 +01:00
|
|
|
<example>
|
|
|
|
<title>Absolute-Value and Factorial Operator Type Resolution</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The <productname>PostgreSQL</productname> operator catalog has several
|
|
|
|
entries for the prefix operator <literal>@</>, all of which implement
|
|
|
|
absolute-value operations for various numeric data types. One of these
|
|
|
|
entries is for type <type>float8</type>, which is the preferred type in
|
|
|
|
the numeric category. Therefore, <productname>PostgreSQL</productname>
|
|
|
|
will use that entry when faced with a non-numeric input:
|
|
|
|
<screen>
|
|
|
|
SELECT @ '-4.5' AS "abs";
|
|
|
|
abs
|
|
|
|
-----
|
|
|
|
4.5
|
|
|
|
(1 row)
|
|
|
|
</screen>
|
|
|
|
Here the system has performed an implicit conversion from <type>text</type> to <type>float8</type>
|
|
|
|
before applying the chosen operator. We can verify that <type>float8</type> and
|
|
|
|
not some other type was used:
|
|
|
|
<screen>
|
|
|
|
SELECT @ '-4.5e500' AS "abs";
|
|
|
|
|
2003-09-13 00:17:24 +02:00
|
|
|
ERROR: "-4.5e500" is out of range for float8
|
2003-03-20 17:17:32 +01:00
|
|
|
</screen>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
On the other hand, the postfix operator <literal>!</> (factorial)
|
|
|
|
is defined only for integer data types, not for <type>float8</type>. So, if we
|
|
|
|
try a similar case with <literal>!</>, we get:
|
|
|
|
<screen>
|
|
|
|
SELECT '20' ! AS "factorial";
|
|
|
|
|
2003-09-13 00:17:24 +02:00
|
|
|
ERROR: operator is not unique: "unknown" !
|
|
|
|
HINT: Could not choose a best candidate operator. You may need to add explicit
|
|
|
|
typecasts.
|
2003-03-20 17:17:32 +01:00
|
|
|
</screen>
|
|
|
|
This happens because the system can't decide which of the several
|
|
|
|
possible <literal>!</> operators should be preferred. We can help
|
|
|
|
it out with an explicit cast:
|
|
|
|
<screen>
|
|
|
|
SELECT CAST('20' AS int8) ! AS "factorial";
|
|
|
|
|
|
|
|
factorial
|
|
|
|
---------------------
|
|
|
|
2432902008176640000
|
|
|
|
(1 row)
|
|
|
|
</screen>
|
|
|
|
</para>
|
|
|
|
</example>
|
|
|
|
|
1998-12-29 03:24:47 +01:00
|
|
|
</sect1>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="typeconv-func">
|
1998-07-08 15:53:15 +02:00
|
|
|
<title>Functions</title>
|
|
|
|
|
2003-08-31 19:32:24 +02:00
|
|
|
<indexterm zone="typeconv-func">
|
|
|
|
<primary>function</primary>
|
|
|
|
<secondary>type resolution in an invocation</secondary>
|
|
|
|
</indexterm>
|
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
The specific function to be used in a function invocation is determined
|
|
|
|
according to the following steps.
|
2001-09-15 02:48:59 +02:00
|
|
|
</para>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<procedure>
|
2003-05-26 02:11:29 +02:00
|
|
|
<title>Function Type Resolution</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2002-04-25 22:14:43 +02:00
|
|
|
Select the functions to be considered from the
|
|
|
|
<classname>pg_proc</classname> system catalog. If an unqualified
|
2003-03-13 02:30:29 +01:00
|
|
|
function name was used, the functions
|
2002-04-25 22:14:43 +02:00
|
|
|
considered are those of the right name and argument count that are
|
2002-09-13 00:05:36 +02:00
|
|
|
visible in the current search path (see <xref linkend="ddl-schemas-path">).
|
2002-04-25 22:14:43 +02:00
|
|
|
If a qualified function name was given, only functions in the specified
|
|
|
|
schema are considered.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<substeps>
|
|
|
|
<step performance="optional">
|
|
|
|
<para>
|
|
|
|
If the search path finds multiple functions of identical argument types,
|
|
|
|
only the one appearing earliest in the path is considered. But functions of
|
|
|
|
different argument types are considered on an equal footing regardless of
|
|
|
|
search path position.
|
|
|
|
</para>
|
|
|
|
</step>
|
|
|
|
</substeps>
|
|
|
|
</step>
|
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
|
|
|
Check for a function accepting exactly the input argument types.
|
|
|
|
If one exists (there can be only one exact match in the set of
|
|
|
|
functions considered), use it.
|
2000-12-17 06:55:26 +01:00
|
|
|
(Cases involving <type>unknown</type> will never find a match at
|
|
|
|
this step.)
|
2003-03-13 02:30:29 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2002-04-25 22:14:43 +02:00
|
|
|
If no exact match is found, see whether the function call appears
|
2003-03-13 02:30:29 +01:00
|
|
|
to be a trivial type conversion request. This happens if the function call
|
2001-10-05 00:06:46 +02:00
|
|
|
has just one argument and the function name is the same as the (internal)
|
|
|
|
name of some data type. Furthermore, the function argument must be either
|
|
|
|
an unknown-type literal or a type that is binary-compatible with the named
|
2003-03-13 02:30:29 +01:00
|
|
|
data type. When these conditions are met, the function argument is converted
|
|
|
|
to the named data type without any actual function call.
|
2001-10-05 00:06:46 +02:00
|
|
|
</para>
|
|
|
|
</step>
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
1998-07-08 15:53:15 +02:00
|
|
|
Look for the best match.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
<substeps>
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2002-04-25 22:14:43 +02:00
|
|
|
Discard candidate functions for which the input types do not match
|
2003-03-13 02:30:29 +01:00
|
|
|
and cannot be converted (using an implicit conversion) to match.
|
2002-04-25 22:14:43 +02:00
|
|
|
<type>unknown</type> literals are
|
2003-03-13 02:30:29 +01:00
|
|
|
assumed to be convertible to anything for this purpose. If only one
|
2002-04-25 22:14:43 +02:00
|
|
|
candidate remains, use it; else continue to the next step.
|
2000-12-17 06:55:26 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2000-12-17 06:55:26 +01:00
|
|
|
Run through all candidates and keep those with the most exact matches
|
2003-05-26 02:11:29 +02:00
|
|
|
on input types. (Domain types are considered the same as their base type
|
|
|
|
for this purpose.) Keep all candidates if none have any exact matches.
|
2000-12-17 06:55:26 +01:00
|
|
|
If only one candidate remains, use it; else continue to the next step.
|
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
Run through all candidates and keep those that accept preferred types (of the
|
|
|
|
input datatype's type category) at the most positions where type conversion
|
|
|
|
will be required.
|
2000-12-17 06:55:26 +01:00
|
|
|
Keep all candidates if none accept preferred types.
|
|
|
|
If only one candidate remains, use it; else continue to the next step.
|
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
If any input arguments are <type>unknown</type>, check the type categories
|
|
|
|
accepted
|
2000-12-17 06:55:26 +01:00
|
|
|
at those argument positions by the remaining candidates. At each position,
|
2003-03-13 02:30:29 +01:00
|
|
|
select the <type>string</type> category if any candidate accepts that category.
|
|
|
|
(This bias towards string
|
|
|
|
is appropriate since an unknown-type literal does look like a string.)
|
2000-12-17 06:55:26 +01:00
|
|
|
Otherwise, if all the remaining candidates accept the same type category,
|
2000-12-19 01:54:59 +01:00
|
|
|
select that category; otherwise fail because
|
2003-03-13 02:30:29 +01:00
|
|
|
the correct choice cannot be deduced without more clues.
|
2003-05-26 02:11:29 +02:00
|
|
|
Now discard candidates that do not accept the selected type category.
|
|
|
|
Furthermore, if any candidate accepts a preferred type at a given argument
|
2000-12-17 06:55:26 +01:00
|
|
|
position, discard candidates that accept non-preferred types for that
|
|
|
|
argument.
|
|
|
|
</para>
|
|
|
|
</step>
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
|
|
|
If only one candidate remains, use it. If no candidate or more than one
|
|
|
|
candidate remains,
|
2000-12-19 01:54:59 +01:00
|
|
|
then fail.
|
2000-12-17 06:55:26 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
</substeps>
|
1998-12-29 03:24:47 +01:00
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
</procedure>
|
2000-12-17 06:55:26 +01:00
|
|
|
|
2003-03-13 02:30:29 +01:00
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
Note that the <quote>best match</> rules are identical for operator and
|
|
|
|
function type resolution.
|
2003-03-13 02:30:29 +01:00
|
|
|
Some examples follow.
|
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
2003-03-13 02:30:29 +01:00
|
|
|
<title>Rounding Function Argument Type Resolution</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
There is only one <function>round</function> function with two
|
|
|
|
arguments. (The first is <type>numeric</type>, the second is
|
|
|
|
<type>integer</type>.) So the following query automatically converts
|
|
|
|
the first argument of type <type>integer</type> to
|
|
|
|
<type>numeric</type>:
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT round(4, 4);
|
|
|
|
|
|
|
|
round
|
|
|
|
--------
|
|
|
|
4.0000
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2003-03-13 02:30:29 +01:00
|
|
|
That query is actually transformed by the parser to
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT round(CAST (4 AS numeric), 4);
|
|
|
|
</screen>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Since numeric constants with decimal points are initially assigned the
|
|
|
|
type <type>numeric</type>, the following query will require no type
|
|
|
|
conversion and may therefore be slightly more efficient:
|
|
|
|
<screen>
|
|
|
|
SELECT round(4.0, 4);
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
|
|
|
<title>Substring Function Type Resolution</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
There are several <function>substr</function> functions, one of which
|
|
|
|
takes types <type>text</type> and <type>integer</type>. If called
|
|
|
|
with a string constant of unspecified type, the system chooses the
|
|
|
|
candidate function that accepts an argument of the preferred category
|
|
|
|
<literal>string</literal> (namely of type <type>text</type>).
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT substr('1234', 3);
|
|
|
|
|
2000-03-26 20:32:30 +02:00
|
|
|
substr
|
|
|
|
--------
|
|
|
|
34
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
If the string is declared to be of type <type>varchar</type>, as might be the case
|
2003-03-13 02:30:29 +01:00
|
|
|
if it comes from a table, then the parser will try to convert it to become <type>text</type>:
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT substr(varchar '1234', 3);
|
|
|
|
|
2000-03-26 20:32:30 +02:00
|
|
|
substr
|
|
|
|
--------
|
|
|
|
34
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
|
|
|
|
This is transformed by the parser to effectively become
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT substr(CAST (varchar '1234' AS text), 3);
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
<para>
|
1998-07-08 15:53:15 +02:00
|
|
|
<note>
|
|
|
|
<para>
|
2003-05-26 02:11:29 +02:00
|
|
|
The parser learns from the <structname>pg_cast</> catalog that
|
|
|
|
<type>text</type> and <type>varchar</type>
|
2003-03-13 02:30:29 +01:00
|
|
|
are binary-compatible, meaning that one can be passed to a function that
|
2000-12-17 06:55:26 +01:00
|
|
|
accepts the other without doing any physical conversion. Therefore, no
|
|
|
|
explicit type conversion call is really inserted in this case.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
</note>
|
2001-09-15 02:48:59 +02:00
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
And, if the function is called with an argument of type <type>integer</type>, the parser will
|
1998-07-08 15:53:15 +02:00
|
|
|
try to convert that to <type>text</type>:
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT substr(1234, 3);
|
|
|
|
|
2000-03-26 20:32:30 +02:00
|
|
|
substr
|
|
|
|
--------
|
|
|
|
34
|
1998-07-08 15:53:15 +02:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
|
|
|
|
This actually executes as
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT substr(CAST (1234 AS text), 3);
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
This automatic transformation can succeed because there is an
|
|
|
|
implicitly invocable cast from <type>integer</type> to
|
|
|
|
<type>text</type>.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
|
|
|
|
1998-12-29 03:24:47 +01:00
|
|
|
</sect1>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="typeconv-query">
|
2003-03-13 02:30:29 +01:00
|
|
|
<title>Value Storage</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-10-15 03:00:59 +02:00
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
Values to be inserted into a table are converted to the destination
|
2002-01-20 23:19:57 +01:00
|
|
|
column's data type according to the
|
2001-10-15 03:00:59 +02:00
|
|
|
following steps.
|
|
|
|
</para>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<procedure>
|
2003-03-13 02:30:29 +01:00
|
|
|
<title>Value Storage Type Conversion</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
|
|
|
Check for an exact match with the target.
|
2003-03-13 02:30:29 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
Otherwise, try to convert the expression to the target type. This will succeed
|
|
|
|
if there is a registered cast between the two types.
|
|
|
|
If the expression is an unknown-type literal, the contents of
|
2000-12-17 06:55:26 +01:00
|
|
|
the literal string will be fed to the input conversion routine for the target
|
|
|
|
type.
|
2003-03-13 02:30:29 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
If the target is a fixed-length type (e.g., <type>char</type> or <type>varchar</type>
|
2000-12-17 06:55:26 +01:00
|
|
|
declared with a length) then try to find a sizing function for the target
|
|
|
|
type. A sizing function is a function of the same name as the type,
|
2003-03-13 02:30:29 +01:00
|
|
|
taking two arguments of which the first is that type and the second is of type
|
|
|
|
<type>integer</type>, and returning the same type. If one is found, it is applied,
|
2000-12-17 06:55:26 +01:00
|
|
|
passing the column's declared length as the second parameter.
|
2003-03-13 02:30:29 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
</procedure>
|
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
2001-10-15 03:00:59 +02:00
|
|
|
<title><type>character</type> Storage Type Conversion</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
For a target column declared as <type>character(20)</type> the following statement
|
|
|
|
ensures that the stored value is sized correctly:
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
CREATE TABLE vv (v character(20));
|
|
|
|
INSERT INTO vv SELECT 'abc' || 'def';
|
|
|
|
SELECT v, length(v) FROM vv;
|
|
|
|
|
2001-10-15 03:00:59 +02:00
|
|
|
v | length
|
|
|
|
----------------------+--------
|
|
|
|
abcdef | 20
|
2000-12-17 06:55:26 +01:00
|
|
|
(1 row)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
</para>
|
2000-12-17 06:55:26 +01:00
|
|
|
|
2003-03-13 02:30:29 +01:00
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
What has really happened here is that the two unknown literals are resolved
|
2001-10-15 03:00:59 +02:00
|
|
|
to <type>text</type> by default, allowing the <literal>||</literal> operator
|
|
|
|
to be resolved as <type>text</type> concatenation. Then the <type>text</type>
|
2003-03-13 02:30:29 +01:00
|
|
|
result of the operator is converted to <type>bpchar</type> (<quote>blank-padded
|
|
|
|
char</>, the internal name of the <type>character</type> data type) to match the target
|
|
|
|
column type. (Since the types <type>text</type> and
|
|
|
|
<type>bpchar</type> are binary-compatible, this conversion does
|
2001-10-15 03:00:59 +02:00
|
|
|
not insert any real function call.) Finally, the sizing function
|
2003-03-13 02:30:29 +01:00
|
|
|
<literal>bpchar(bpchar, integer)</literal> is found in the system catalog
|
2001-10-15 03:00:59 +02:00
|
|
|
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.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
1998-12-29 03:24:47 +01:00
|
|
|
</sect1>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2000-12-17 06:55:26 +01:00
|
|
|
<sect1 id="typeconv-union-case">
|
2003-08-31 19:32:24 +02:00
|
|
|
<title><literal>UNION</literal>, <literal>CASE</literal>, and <literal>ARRAY</literal> Constructs</title>
|
|
|
|
|
|
|
|
<indexterm zone="typeconv-union-case">
|
|
|
|
<primary>UNION</primary>
|
|
|
|
<secondary>determination of result type</secondary>
|
|
|
|
</indexterm>
|
|
|
|
|
|
|
|
<indexterm zone="typeconv-union-case">
|
|
|
|
<primary>CASE</primary>
|
|
|
|
<secondary>determination of result type</secondary>
|
|
|
|
</indexterm>
|
|
|
|
|
|
|
|
<indexterm zone="typeconv-union-case">
|
|
|
|
<primary>ARRAY</primary>
|
|
|
|
<secondary>determination of result type</secondary>
|
|
|
|
</indexterm>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-10-15 03:00:59 +02:00
|
|
|
SQL <literal>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 <literal>INTERSECT</> and
|
|
|
|
<literal>EXCEPT</> constructs resolve dissimilar types in the same way as
|
|
|
|
<literal>UNION</>.
|
2003-08-15 01:13:27 +02:00
|
|
|
A <literal>CASE</> construct uses the identical algorithm to match up its
|
|
|
|
component expressions and select a result data type, as does <literal>ARRAY</>.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2003-03-13 02:30:29 +01:00
|
|
|
|
1998-07-08 15:53:15 +02:00
|
|
|
<procedure>
|
2003-08-15 01:13:27 +02:00
|
|
|
<title><literal>UNION</literal>, <literal>CASE</literal>, and
|
|
|
|
<literal>ARRAY</literal> Type Resolution</title>
|
2000-12-17 06:55:26 +01:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
|
|
|
If all inputs are of type <type>unknown</type>, resolve as type
|
2003-03-13 02:30:29 +01:00
|
|
|
<type>text</type> (the preferred type of the string category).
|
|
|
|
Otherwise, ignore the <type>unknown</type> inputs while choosing the result type.
|
|
|
|
</para>
|
|
|
|
</step>
|
2000-12-17 06:55:26 +01:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2000-12-19 01:54:59 +01:00
|
|
|
If the non-unknown inputs are not all of the same type category, fail.
|
2003-03-13 02:30:29 +01:00
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
Choose the first non-unknown input type which is a preferred type in
|
|
|
|
that category or allows all the non-unknown inputs to be implicitly
|
2003-03-13 02:30:29 +01:00
|
|
|
converted to it.
|
|
|
|
</para>
|
|
|
|
</step>
|
2000-12-17 06:55:26 +01:00
|
|
|
|
|
|
|
<step performance="required">
|
|
|
|
<para>
|
2003-03-13 02:30:29 +01:00
|
|
|
Convert all inputs to the selected type.
|
|
|
|
</para>
|
|
|
|
</step>
|
1998-07-08 15:53:15 +02:00
|
|
|
</procedure>
|
|
|
|
|
2003-03-13 02:30:29 +01:00
|
|
|
<para>
|
|
|
|
Some examples follow.
|
|
|
|
</para>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
2003-03-13 02:30:29 +01:00
|
|
|
<title>Type Resolution with Underspecified Types in a Union</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT text 'a' AS "text" UNION SELECT 'b';
|
|
|
|
|
|
|
|
text
|
2000-03-26 20:32:30 +02:00
|
|
|
------
|
|
|
|
a
|
|
|
|
b
|
1998-07-08 15:53:15 +02:00
|
|
|
(2 rows)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
Here, the unknown-type literal <literal>'b'</literal> will be resolved as type <type>text</type>.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
2003-03-13 02:30:29 +01:00
|
|
|
<title>Type Resolution in a Simple Union</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT 1.2 AS "numeric" UNION SELECT 1;
|
|
|
|
|
|
|
|
numeric
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
---------
|
|
|
|
1
|
|
|
|
1.2
|
1998-07-08 15:53:15 +02:00
|
|
|
(2 rows)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
The literal <literal>1.2</> is of type <type>numeric</>,
|
2003-03-13 02:30:29 +01:00
|
|
|
and the <type>integer</type> value <literal>1</> can be cast implicitly to
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
<type>numeric</>, so that type is used.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
2001-09-15 02:48:59 +02:00
|
|
|
<example>
|
2003-03-13 02:30:29 +01:00
|
|
|
<title>Type Resolution in a Transposed Union</title>
|
1998-07-08 15:53:15 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 02:48:59 +02:00
|
|
|
<screen>
|
2003-03-13 02:30:29 +01:00
|
|
|
SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
|
|
|
|
|
|
|
|
real
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
------
|
|
|
|
1
|
|
|
|
2.2
|
2000-12-17 06:55:26 +01:00
|
|
|
(2 rows)
|
2001-09-15 02:48:59 +02:00
|
|
|
</screen>
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
Here, since type <type>real</> cannot be implicitly cast to <type>integer</>,
|
|
|
|
but <type>integer</> can be implicitly cast to <type>real</>, the union
|
|
|
|
result type is resolved as <type>real</>.
|
1998-12-29 03:24:47 +01:00
|
|
|
</para>
|
2001-09-15 02:48:59 +02:00
|
|
|
</example>
|
|
|
|
|
1998-12-29 03:24:47 +01:00
|
|
|
</sect1>
|
1998-07-08 15:53:15 +02:00
|
|
|
</chapter>
|
2000-05-02 22:02:03 +02:00
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
|
|
|
mode:sgml
|
|
|
|
sgml-omittag:t
|
|
|
|
sgml-shorttag:t
|
|
|
|
sgml-minimize-attributes:nil
|
|
|
|
sgml-always-quote-attributes:t
|
|
|
|
sgml-indent-step:1
|
|
|
|
sgml-indent-data:t
|
|
|
|
sgml-parent-document:nil
|
|
|
|
sgml-default-dtd-file:"./reference.ced"
|
|
|
|
sgml-exposed-tags:nil
|
|
|
|
sgml-local-catalogs:("/usr/lib/sgml/catalog")
|
|
|
|
sgml-local-ecat-files:nil
|
|
|
|
End:
|
|
|
|
-->
|