aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/catalogs.sgml27
-rw-r--r--doc/src/sgml/datatype.sgml68
-rw-r--r--doc/src/sgml/ref/create_cast.sgml75
-rw-r--r--doc/src/sgml/release.sgml4
-rw-r--r--doc/src/sgml/typeconv.sgml50
5 files changed, 144 insertions, 80 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index a8fd81e19c9..01dfe6ad73b 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,6 +1,6 @@
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
- $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.59 2002/09/03 01:04:40 tgl Exp $
+ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.60 2002/09/18 21:35:20 tgl Exp $
-->
<chapter id="catalogs">
@@ -841,9 +841,8 @@
<title>pg_cast</title>
<para>
- <structname>pg_cast</structname> stores data type conversion paths
- defined with <command>CREATE CAST</command> plus the built-in
- conversions.
+ <structname>pg_cast</structname> stores data type conversion paths,
+ both built-in paths and those defined with <command>CREATE CAST</command>.
</para>
<table>
@@ -879,17 +878,25 @@
<entry><type>oid</type></entry>
<entry>pg_proc.oid</entry>
<entry>
- The OID of the function to use to perform this cast. A 0 is
- stored if the data types are binary compatible (that is, no
- function is needed to perform the cast).
+ The OID of the function to use to perform this cast. Zero is
+ stored if the data types are binary coercible (that is, no
+ run-time operation is needed to perform the cast).
</entry>
</row>
<row>
- <entry>castimplicit</entry>
- <entry><type>bool</type></entry>
+ <entry>castcontext</entry>
+ <entry><type>char</type></entry>
<entry></entry>
- <entry>Indication whether this cast can be invoked implicitly</entry>
+ <entry>
+ Indicates what contexts the cast may be invoked in.
+ <literal>e</> means only as an explicit cast (using
+ <literal>CAST</>, <literal>::</>, or function-call syntax).
+ <literal>a</> means implicitly in assignment
+ to a target column, as well as explicitly.
+ <literal>i</> means implicitly in expressions, as well as the
+ other cases.
+ </entry>
</row>
</tbody>
</tgroup>
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 41ca3c00e53..28d3fcb7ede 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.102 2002/08/23 02:54:18 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.103 2002/09/18 21:35:20 tgl Exp $
-->
<chapter id="datatype">
@@ -823,8 +823,19 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
<note>
<para>
- Prior to <productname>PostgreSQL</> 7.2, strings that were too long were silently
- truncated, no error was raised.
+ If one explicitly casts a value to
+ <type>character(<replaceable>n</>)</type> or <type>character
+ varying(<replaceable>n</>)</type>, then an overlength value will
+ be truncated to <replaceable>n</> characters without raising an
+ error. (This too is required by the SQL standard.)
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</> 7.2, strings that were too long were
+ always truncated without raising an error, in either explicit or
+ implicit casting contexts.
</para>
</note>
@@ -897,12 +908,14 @@ INSERT INTO test2 VALUES ('ok');
INSERT INTO test2 VALUES ('good ');
INSERT INTO test2 VALUES ('too long');
<computeroutput>ERROR: value too long for type character varying(5)</computeroutput>
+INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation
SELECT b, char_length(b) FROM test2;
<computeroutput>
b | char_length
-------+-------------
ok | 2
good | 5
+ too l | 5
</computeroutput>
</programlisting>
<calloutlist>
@@ -932,7 +945,7 @@ SELECT b, char_length(b) FROM test2;
</para>
<table tocentry="1">
- <title>Specialty Character Type</title>
+ <title>Specialty Character Types</title>
<tgroup cols="3">
<thead>
<row>
@@ -2832,29 +2845,39 @@ SELECT * FROM test1 WHERE a;
<para>
Bit strings are strings of 1's and 0's. They can be used to store
or visualize bit masks. There are two SQL bit types:
- <type>BIT(<replaceable>x</replaceable>)</type> and <type>BIT
- VARYING(<replaceable>x</replaceable>)</type>; where
- <replaceable>x</replaceable> is a positive integer.
+ <type>BIT(<replaceable>n</replaceable>)</type> and <type>BIT
+ VARYING(<replaceable>n</replaceable>)</type>, where
+ <replaceable>n</replaceable> is a positive integer.
</para>
<para>
<type>BIT</type> type data must match the length
- <replaceable>x</replaceable> exactly; it is an error to attempt to
- store shorter or longer bit strings. <type>BIT VARYING</type> is
+ <replaceable>n</replaceable> exactly; it is an error to attempt to
+ store shorter or longer bit strings. <type>BIT VARYING</type> data is
of variable length up to the maximum length
- <replaceable>x</replaceable>; longer strings will be rejected.
- <type>BIT</type> without length is equivalent to
- <literal>BIT(1)</literal>, <type>BIT VARYING</type> without length
+ <replaceable>n</replaceable>; longer strings will be rejected.
+ Writing <type>BIT</type> without a length is equivalent to
+ <literal>BIT(1)</literal>, while <type>BIT VARYING</type> without a length
specification means unlimited length.
</para>
<note>
<para>
- Prior to <productname>PostgreSQL</> 7.2, <type>BIT</type> type data was
- zero-padded on the right. This was changed to comply with the
- SQL standard. To implement zero-padded bit strings, a
- combination of the concatenation operator and the
- <function>substring</function> function can be used.
+ If one explicitly casts a bit-string value to
+ <type>BIT(<replaceable>n</>)</type>, it will be truncated or
+ zero-padded on the right to be exactly <replaceable>n</> bits,
+ without raising an error. Similarly,
+ if one explicitly casts a bit-string value to
+ <type>BIT VARYING(<replaceable>n</>)</type>, it will be truncated
+ on the right if it is more than <replaceable>n</> bits.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</> 7.2, <type>BIT</type> data was
+ always silently truncated or zero-padded on the right, with or without an
+ explicit cast. This was changed to comply with the SQL standard.
</para>
</note>
@@ -2874,9 +2897,16 @@ CREATE TABLE test (a BIT(3), b BIT VARYING(5));
INSERT INTO test VALUES (B'101', B'00');
INSERT INTO test VALUES (B'10', B'101');
<computeroutput>
-ERROR: bit string length does not match type bit(3)
+ERROR: Bit string length 2 does not match type BIT(3)
+</computeroutput>
+INSERT INTO test VALUES (B'10'::bit(3), B'101');
+SELECT * FROM test;
+<computeroutput>
+ a | b
+-----+-----
+ 101 | 00
+ 100 | 101
</computeroutput>
-SELECT SUBSTRING(b FROM 1 FOR 2) FROM test;
</programlisting>
</example>
diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml
index bc9f71e566e..e64d696f81a 100644
--- a/doc/src/sgml/ref/create_cast.sgml
+++ b/doc/src/sgml/ref/create_cast.sgml
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.4 2002/09/15 13:04:16 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.5 2002/09/18 21:35:20 tgl Exp $ -->
<refentry id="SQL-CREATECAST">
<refmeta>
@@ -15,11 +15,11 @@
<synopsis>
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
WITH FUNCTION <replaceable>funcname</replaceable> (<replaceable>argtype</replaceable>)
- [AS ASSIGNMENT]
+ [ AS ASSIGNMENT | AS IMPLICIT ]
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
WITHOUT FUNCTION
- [AS ASSIGNMENT]
+ [ AS ASSIGNMENT | AS IMPLICIT ]
</synopsis>
</refsynopsisdiv>
@@ -49,20 +49,44 @@ SELECT CAST(42 AS text);
</para>
<para>
- A cast can be marked <literal>AS ASSIGNMENT</>, which means that it
- can be invoked implicitly in any context where the conversion it
- defines is required. Cast functions not so marked can be invoked
- only by explicit <literal>CAST</>,
+ By default, a cast can be invoked only by an explicit cast request,
+ that is an explicit <literal>CAST(<replaceable>x</> AS
+ <replaceable>typename</>)</literal>,
<replaceable>x</><literal>::</><replaceable>typename</>, or
- <replaceable>typename</>(<replaceable>x</>) constructs. For
- example, supposing that <literal>foo.f1</literal> is a column of
+ <replaceable>typename</>(<replaceable>x</>) construct.
+ </para>
+
+ <para>
+ If the cast is marked <literal>AS ASSIGNMENT</> then it can be invoked
+ implicitly when assigning to a column of the target data type.
+ For example, supposing that <literal>foo.f1</literal> is a column of
type <type>text</type>, then
<programlisting>
INSERT INTO foo(f1) VALUES(42);
</programlisting>
will be allowed if the cast from type <type>integer</type> to type
<type>text</type> is marked <literal>AS ASSIGNMENT</>, otherwise
- not. (We generally use the term <firstterm>implicit
+ not.
+ (We generally use the term <firstterm>assignment
+ cast</firstterm> to describe this kind of cast.)
+ </para>
+
+ <para>
+ If the cast is marked <literal>AS IMPLICIT</> then it can be invoked
+ implicitly in any context, whether assignment or internally in an
+ expression. For example, since <literal>||</> takes <type>text</>
+ arguments,
+<programlisting>
+SELECT 'The time is ' || now();
+</programlisting>
+ will be allowed only if the cast from type <type>timestamp</> to
+ <type>text</type> is marked <literal>AS IMPLICIT</>. Otherwise it
+ will be necessary to write one of
+<programlisting>
+SELECT 'The time is ' || CAST(now() AS text);
+SELECT 'The time is ' || now()::text;
+</programlisting>
+ (We generally use the term <firstterm>implicit
cast</firstterm> to describe this kind of cast.)
</para>
@@ -74,10 +98,11 @@ INSERT INTO foo(f1) VALUES(42);
all because there are multiple possible interpretations. A good
rule of thumb is to make a cast implicitly invokable only for
information-preserving transformations between types in the same
- general type category. For example, <type>int2</type> to
- <type>int4</type> casts can reasonably be implicit, but be wary of
- marking <type>int4</type> to <type>text</type> or
- <type>float8</type> to <type>int4</type> as implicit casts.
+ general type category. For example, the cast from <type>int2</type> to
+ <type>int4</type> can reasonably be implicit, but the cast from
+ <type>float8</type> to <type>int4</type> should probably be
+ assignment-only. Cross-type-category casts, such as <type>text</>
+ to <type>int4</>, are best made explicit-only.
</para>
<para>
@@ -138,7 +163,18 @@ INSERT INTO foo(f1) VALUES(42);
<listitem>
<para>
- Indicates that the cast may be invoked implicitly.
+ Indicates that the cast may be invoked implicitly in assignment
+ contexts.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>AS IMPLICIT</literal></term>
+
+ <listitem>
+ <para>
+ Indicates that the cast may be invoked implicitly in any context.
</para>
</listitem>
</varlistentry>
@@ -163,10 +199,10 @@ INSERT INTO foo(f1) VALUES(42);
data type, returned that data type, and took one argument of a
different type was automatically a cast function. This convention has
been abandoned in face of the introduction of schemas and to be
- able to represent binary compatible casts in the catalogs. The built-in
+ able to represent binary compatible casts in the catalogs. (The built-in
cast functions
- still follow this naming scheme, but they have to be declared as
- casts explicitly now.
+ still follow this naming scheme, but they have to be shown as
+ casts in <literal>pg_cast</> now.)
</para>
</refsect1>
@@ -191,7 +227,8 @@ CREATE CAST (text AS int4) WITH FUNCTION int4(text);
<para>
The <command>CREATE CAST</command> command conforms to SQL99,
except that SQL99 does not make provisions for binary compatible
- types.
+ types. <literal>AS IMPLICIT</> is a <productname>PostgreSQL</productname>
+ extension, too.
</para>
</refsect1>
diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml
index b7f2b4be71b..f373cc6e25d 100644
--- a/doc/src/sgml/release.sgml
+++ b/doc/src/sgml/release.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.158 2002/09/04 07:16:32 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.159 2002/09/18 21:35:20 tgl Exp $
-->
<appendix id="release">
@@ -24,6 +24,8 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
+Mixed numeric-and-float expressions are evaluated as float, per SQL spec
+Explicit casts to char, varchar, bit, varbit will truncate or pad without error
CREATE OR REPLACE VIEW, CREATE OR REPLACE RULE are available
No-autocommit mode is available (set autocommit to off)
Substantial improvements in functionality for functions returning sets
diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml
index 0bfc40b1edf..e6ff564be96 100644
--- a/doc/src/sgml/typeconv.sgml
+++ b/doc/src/sgml/typeconv.sgml
@@ -804,13 +804,9 @@ If the non-unknown inputs are not all of the same type category, fail.
<step performance="required">
<para>
-If one or more non-unknown inputs are of a preferred type in that category,
-resolve as that type.
-</para></step>
-
-<step performance="required">
-<para>
-Otherwise, resolve as the type of the first non-unknown input.
+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
+coerced to it.
</para></step>
<step performance="required">
@@ -842,15 +838,16 @@ Here, the unknown-type literal <literal>'b'</literal> will be resolved as type t
<para>
<screen>
-tgl=> SELECT 1.2 AS "Double" UNION SELECT 1;
- Double
---------
- 1
- 1.2
+tgl=> SELECT 1.2 AS "Numeric" UNION SELECT 1;
+ Numeric
+---------
+ 1
+ 1.2
(2 rows)
</screen>
-The literal <literal>1.2</> is of type <type>double precision</>,
-the preferred type in the numeric category, so that type is used.
+The literal <literal>1.2</> is of type <type>numeric</>,
+and the integer value <literal>1</> can be cast implicitly to
+<type>numeric</>, so that type is used.
</para>
</example>
@@ -858,27 +855,18 @@ the preferred type in the numeric category, so that type is used.
<title>Type Conversion in a Transposed Union</title>
<para>
-Here the output type of the union is forced to match the type of
-the first clause in the union:
-
<screen>
-tgl=> SELECT 1 AS "All integers"
+tgl=> SELECT 1 AS "Real"
tgl-> UNION SELECT CAST('2.2' AS REAL);
- All integers
---------------
- 1
- 2
+ Real
+------
+ 1
+ 2.2
(2 rows)
</screen>
-</para>
-<para>
-Since <type>REAL</type> is not a preferred type, the parser sees no reason
-to select it over <type>INTEGER</type> (which is what the 1 is), and instead
-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
-<productname>PostgreSQL</productname> may support a more general notion of
-type preferences.
+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</>.
</para>
</example>