1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

pg_cast table, and standards-compliant CREATE/DROP CAST commands, plus

extension to create binary compatible casts.  Includes dependency tracking
as well.

pg_proc.proimplicit is now defunct, but will be removed in a separate
commit.

pg_dump provides a migration path from the previous scheme to declare
casts.  Dumping binary compatible casts is currently impossible, though.
This commit is contained in:
Peter Eisentraut
2002-07-18 23:11:32 +00:00
parent a345ac8842
commit 97377048b4
36 changed files with 1299 additions and 343 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.40 2002/07/18 16:47:22 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.41 2002/07/18 23:11:27 petere Exp $
PostgreSQL documentation
Complete list of usable sgml source files in this directory.
-->
@ -51,6 +51,7 @@ Complete list of usable sgml source files in this directory.
<!entity commit system "commit.sgml">
<!entity copyTable system "copy.sgml">
<!entity createAggregate system "create_aggregate.sgml">
<!entity createCast system "create_cast.sgml">
<!entity createConstraint system "create_constraint.sgml">
<!entity createDatabase system "create_database.sgml">
<!entity createDomain system "create_domain.sgml">
@ -71,6 +72,7 @@ Complete list of usable sgml source files in this directory.
<!entity declare system "declare.sgml">
<!entity delete system "delete.sgml">
<!entity dropAggregate system "drop_aggregate.sgml">
<!entity dropCast system "drop_cast.sgml">
<!entity dropDatabase system "drop_database.sgml">
<!entity dropDomain system "drop_domain.sgml">
<!entity dropFunction system "drop_function.sgml">

View File

@ -0,0 +1,232 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.1 2002/07/18 23:11:27 petere Exp $ -->
<refentry id="SQL-CREATECAST">
<refmeta>
<refentrytitle id="SQL-CREATECAST-TITLE">CREATE CAST</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>CREATE CAST</refname>
<refpurpose>define a user-defined cast</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
WITH FUNCTION <replaceable>funcname</replaceable> (<replaceable>argtype</replaceable>)
[AS ASSIGNMENT]
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
WITHOUT FUNCTION
[AS ASSIGNMENT]
</synopsis>
</refsynopsisdiv>
<refsect1 id="sql-createcast-description">
<title>Description</title>
<para>
<command>CREATE CAST</command> defines a new cast. A cast
specifies which function can be invoked when a conversion between
two data types is requested. For example,
<programlisting>
SELECT CAST(42 AS text);
</programlisting>
converts the integer constant 42 to type <type>text</type> by
invoking a previously specified function, in this case
<literal>text(int4)</>. (If no suitable cast has been defined, the
conversion fails.)
</para>
<para>
Two types may be <firstterm>binary compatible</firstterm>, which
means that they can be converted into one another <quote>for
free</quote> without invoking any function. This requires that
corresponding values use the same internal representation. For
instance, the types <type>text</type> and <type>varchar</type> are
binary compatible.
</para>
<para>
A cast can 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</>,
<replaceable>x</><literal>::</><replaceable>typename</>, or
<replaceable>typename</>(<replaceable>x</>) constructs. 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
cast</firstterm> to describe this kind of cast.)
</para>
<para>
It is wise to be conservative about marking casts as implicit. An
overabundance of implicit casting paths can cause
<productname>PostgreSQL</productname> to choose surprising
interpretations of commands, or to be unable to resolve commands at
all because there are multiple possible interpretations. A good
rule of thumb is to make 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.
</para>
<para>
To be able to create a cast, you must own the underlying function.
To be able to create a binary compatible cast, you must own both
the source and the target data type.
</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term><replaceable>sourcetype</replaceable></term>
<listitem>
<para>
The name of the source data type of the cast.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>targettype</replaceable></term>
<listitem>
<para>
The name of the target data type of the cast.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>funcname</replaceable>(<replaceable>argtype</replaceable>)</term>
<listitem>
<para>
The function used to perform the cast. The function name may
be schema-qualified. If it is not, the function will be looked
up in the path. The argument type must be identical to the
source type, the result data type must match the target type of
the cast. Cast functions must be marked immutable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>WITHOUT FUNCTION</literal></term>
<listitem>
<para>
Indicates that the source type and the target type are binary
compatible, so no function is required to perform the cast.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>AS ASSIGNMENT</literal></term>
<listitem>
<para>
Indicates that the cast may be invoked implicitly.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="sql-createcast-notes">
<title>Notes</title>
<para>
Use <command>DROP CAST</command> to remove user-defined casts.
</para>
<para>
The privileges required to create a cast may be changed in a future
release.
</para>
<para>
Remember that if you want to be able to convert types both ways you
need to declare casts both ways explicitly.
</para>
<para>
Prior to PostgreSQL 7.3, every function that had the same name as a
data type, returned that data type, and took one argument of a
different type was automatically a cast function. This system has
been abandoned in face of the introduction of schemas and to be
able to store binary compatible casts. The built-in cast functions
still follow this naming scheme, but they have to be declared as
casts explicitly now.
</para>
</refsect1>
<refsect1 id="sql-createcast-examples">
<title>Examples</title>
<para>
To create a cast from type <type>text</type> to type
<type>int</type> using the function <literal>int4(text)</literal>:
<programlisting>
CREATE CAST (text AS int4) WITH FUNCTION int4(text);
</programlisting>
(This cast is already predefined in the system.)
</para>
</refsect1>
<refsect1 id="sql-createcast-compat">
<title>Compatibility</title>
<para>
The <command>CREATE CAST</command> command conforms to SQL99,
except that SQL99 does not make provisions for binary compatible
types.
</para>
</refsect1>
<refsect1 id="sql-createcast-seealso">
<title>See Also</title>
<para>
<xref linkend="sql-createfunction" endterm="sql-createfunction-title">,
<xref linkend="sql-createtype" endterm="sql-createtype-title">,
<xref linkend="sql-dropcast" endterm="sql-dropcast-title">,
<citetitle>PostgreSQL Programmer's Guide</citetitle>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
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:
-->

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.39 2002/05/18 13:47:59 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.40 2002/07/18 23:11:27 petere Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
@ -20,7 +20,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
{ LANGUAGE <replaceable class="parameter">langname</replaceable>
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| IMPLICIT CAST
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
| AS '<replaceable class="parameter">definition</replaceable>'
| AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
@ -188,18 +187,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>IMPLICIT CAST</literal</term>
<listitem>
<para>
Indicates that the function may be used for implicit type
conversions. See <xref linkend="sql-createfunction-cast-functions"
endterm="sql-createfunction-cast-functions-title"> for more detail.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><optional>EXTERNAL</optional> SECURITY INVOKER</term>
<term><optional>EXTERNAL</optional> SECURITY DEFINER</term>
@ -285,14 +272,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term>implicitCoercion</term>
<listitem>
<para>
Same as <literal>IMPLICIT CAST</literal>
</para>
</listitem>
</varlistentry>
</variablelist>
Attribute names are not case-sensitive.
@ -394,55 +373,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</para>
</refsect1>
<refsect1 id="sql-createfunction-cast-functions">
<title id="sql-createfunction-cast-functions-title">
Type Cast Functions
</title>
<para>
A function that has one argument and is named the same as its return
data type (including the schema name) is considered to be a <firstterm>type
casting function</>: it can be invoked to convert a value of its input
data type into a value
of its output datatype. For example,
<programlisting>
SELECT CAST(42 AS text);
</programlisting>
converts the integer constant 42 to text by invoking a function
<literal>text(int4)</>, if such a function exists and returns type
text. (If no suitable conversion function can be found, the cast fails.)
</para>
<para>
If a potential cast function is marked <literal>IMPLICIT CAST</>,
then 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</>,
<replaceable>x</><literal>::</><replaceable>typename</>, or
<replaceable>typename</>(<replaceable>x</>) constructs. 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 <literal>text(int4)</> is marked
<literal>IMPLICIT CAST</>, otherwise not.
</para>
<para>
It is wise to be conservative about marking cast functions as
implicit casts. An overabundance of implicit casting paths can
cause <productname>PostgreSQL</productname> to choose surprising
interpretations of commands, or to be unable to resolve commands at
all because there are multiple possible interpretations. A good
rule of thumb is to make 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.
</para>
</refsect1>
<refsect1 id="sql-createfunction-examples">
<title>Examples</title>

View File

@ -0,0 +1,133 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_cast.sgml,v 1.1 2002/07/18 23:11:27 petere Exp $ -->
<refentry id="SQL-DROPCAST">
<refmeta>
<refentrytitle id="SQL-DROPCAST-TITLE">DROP CAST</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>DROP CAST</refname>
<refpurpose>remove a user-defined cast</refpurpose>
</refnamediv>
<refsynopsisdiv>
<synopsis>
DROP CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
[ CASCADE | RESTRICT ]
</synopsis>
</refsynopsisdiv>
<refsect1 id="sql-dropcast-description">
<title>Description</title>
<para>
<command>DROP CAST</command> removes a previously defined cast.
</para>
<para>
To be able to drop a cast, you must own the underlying function.
To be able to drop a binary compatible cast, you must own both the
source and the target data type. These are the same privileges
that are required to create a cast.
</para>
<variablelist>
<title>Parameters</title>
<varlistentry>
<term><replaceable>sourcetype</replaceable></term>
<listitem>
<para>
The name of the source data type of the cast.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>targettype</replaceable></term>
<listitem>
<para>
The name of the target data type of the cast.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CASCADE</literal></term>
<term><literal>RESTRICT</literal></term>
<listitem>
<para>
These key words do not have any effect, since there are no
dependencies on casts.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="sql-dropcast-notes">
<title>Notes</title>
<para>
Use <command>CREATE CAST</command> to create user-defined casts.
</para>
<para>
The privileges required to drop a cast may be changed in a future
release.
</para>
</refsect1>
<refsect1 id="sql-dropcast-examples">
<title>Examples</title>
<para>
To drop the cast from type <type>text</type> to type <type>int</type>:
<programlisting>
DROP CAST (text AS int4);
</programlisting>
</para>
</refsect1>
<refsect1 id="sql-dropcast-compat">
<title>Compatibility</title>
<para>
The <command>DROP CAST</command> command conforms to SQL99.
</para>
</refsect1>
<refsect1 id="sql-dropcast-seealso">
<title>See Also</title>
<para>
<xref linkend="sql-createcast" endterm="sql-createcast-title">
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-omittag:nil
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:
-->

View File

@ -1,5 +1,5 @@
<!-- reference.sgml
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.29 2002/07/18 16:47:22 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.30 2002/07/18 23:11:27 petere Exp $
PostgreSQL Reference Manual
-->
@ -60,6 +60,7 @@ PostgreSQL Reference Manual
&commit;
&copyTable;
&createAggregate;
&createCast;
&createConstraint;
&createDatabase;
&createDomain;
@ -80,6 +81,7 @@ PostgreSQL Reference Manual
&declare;
&delete;
&dropAggregate;
&dropCast;
&dropDatabase;
&dropDomain;
&dropFunction;

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.141 2002/07/16 22:12:18 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.142 2002/07/18 23:11:27 petere Exp $
-->
<appendix id="release">
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
CREATE CAST/DROP CAST
Sequences created by SERIAL column definitions now auto-drop with the column
Most forms of DROP now support RESTRICT and CASCADE options
Recursive SQL functions can be defined