mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +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:
@ -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
|
PostgreSQL documentation
|
||||||
Complete list of usable sgml source files in this directory.
|
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 commit system "commit.sgml">
|
||||||
<!entity copyTable system "copy.sgml">
|
<!entity copyTable system "copy.sgml">
|
||||||
<!entity createAggregate system "create_aggregate.sgml">
|
<!entity createAggregate system "create_aggregate.sgml">
|
||||||
|
<!entity createCast system "create_cast.sgml">
|
||||||
<!entity createConstraint system "create_constraint.sgml">
|
<!entity createConstraint system "create_constraint.sgml">
|
||||||
<!entity createDatabase system "create_database.sgml">
|
<!entity createDatabase system "create_database.sgml">
|
||||||
<!entity createDomain system "create_domain.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 declare system "declare.sgml">
|
||||||
<!entity delete system "delete.sgml">
|
<!entity delete system "delete.sgml">
|
||||||
<!entity dropAggregate system "drop_aggregate.sgml">
|
<!entity dropAggregate system "drop_aggregate.sgml">
|
||||||
|
<!entity dropCast system "drop_cast.sgml">
|
||||||
<!entity dropDatabase system "drop_database.sgml">
|
<!entity dropDatabase system "drop_database.sgml">
|
||||||
<!entity dropDomain system "drop_domain.sgml">
|
<!entity dropDomain system "drop_domain.sgml">
|
||||||
<!entity dropFunction system "drop_function.sgml">
|
<!entity dropFunction system "drop_function.sgml">
|
||||||
|
232
doc/src/sgml/ref/create_cast.sgml
Normal file
232
doc/src/sgml/ref/create_cast.sgml
Normal 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:
|
||||||
|
-->
|
@ -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">
|
<refentry id="SQL-CREATEFUNCTION">
|
||||||
@ -20,7 +20,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
|||||||
{ LANGUAGE <replaceable class="parameter">langname</replaceable>
|
{ LANGUAGE <replaceable class="parameter">langname</replaceable>
|
||||||
| IMMUTABLE | STABLE | VOLATILE
|
| IMMUTABLE | STABLE | VOLATILE
|
||||||
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
|
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
|
||||||
| IMPLICIT CAST
|
|
||||||
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
|
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
|
||||||
| AS '<replaceable class="parameter">definition</replaceable>'
|
| AS '<replaceable class="parameter">definition</replaceable>'
|
||||||
| AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</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>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><optional>EXTERNAL</optional> SECURITY INVOKER</term>
|
<term><optional>EXTERNAL</optional> SECURITY INVOKER</term>
|
||||||
<term><optional>EXTERNAL</optional> SECURITY DEFINER</term>
|
<term><optional>EXTERNAL</optional> SECURITY DEFINER</term>
|
||||||
@ -285,14 +272,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>implicitCoercion</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Same as <literal>IMPLICIT CAST</literal>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
Attribute names are not case-sensitive.
|
Attribute names are not case-sensitive.
|
||||||
@ -394,55 +373,6 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
|
|||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</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">
|
<refsect1 id="sql-createfunction-examples">
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
|
133
doc/src/sgml/ref/drop_cast.sgml
Normal file
133
doc/src/sgml/ref/drop_cast.sgml
Normal 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:
|
||||||
|
-->
|
@ -1,5 +1,5 @@
|
|||||||
<!-- reference.sgml
|
<!-- 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
|
PostgreSQL Reference Manual
|
||||||
-->
|
-->
|
||||||
@ -60,6 +60,7 @@ PostgreSQL Reference Manual
|
|||||||
&commit;
|
&commit;
|
||||||
©Table;
|
©Table;
|
||||||
&createAggregate;
|
&createAggregate;
|
||||||
|
&createCast;
|
||||||
&createConstraint;
|
&createConstraint;
|
||||||
&createDatabase;
|
&createDatabase;
|
||||||
&createDomain;
|
&createDomain;
|
||||||
@ -80,6 +81,7 @@ PostgreSQL Reference Manual
|
|||||||
&declare;
|
&declare;
|
||||||
&delete;
|
&delete;
|
||||||
&dropAggregate;
|
&dropAggregate;
|
||||||
|
&dropCast;
|
||||||
&dropDatabase;
|
&dropDatabase;
|
||||||
&dropDomain;
|
&dropDomain;
|
||||||
&dropFunction;
|
&dropFunction;
|
||||||
|
@ -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">
|
<appendix id="release">
|
||||||
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
|
|||||||
worries about funny characters.
|
worries about funny characters.
|
||||||
-->
|
-->
|
||||||
<literallayout><![CDATA[
|
<literallayout><![CDATA[
|
||||||
|
CREATE CAST/DROP CAST
|
||||||
Sequences created by SERIAL column definitions now auto-drop with the column
|
Sequences created by SERIAL column definitions now auto-drop with the column
|
||||||
Most forms of DROP now support RESTRICT and CASCADE options
|
Most forms of DROP now support RESTRICT and CASCADE options
|
||||||
Recursive SQL functions can be defined
|
Recursive SQL functions can be defined
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for backend/catalog
|
# Makefile for backend/catalog
|
||||||
#
|
#
|
||||||
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.41 2002/07/12 18:43:13 tgl Exp $
|
# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.42 2002/07/18 23:11:27 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
|
|||||||
pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \
|
pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \
|
||||||
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
|
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
|
||||||
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
|
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
|
||||||
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
|
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
|
||||||
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
|
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
|
||||||
pg_depend.h indexing.h \
|
pg_depend.h indexing.h \
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.4 2002/07/18 16:47:22 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.5 2002/07/18 23:11:27 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -47,6 +47,7 @@
|
|||||||
/* This enum covers all system catalogs whose OIDs can appear in classid. */
|
/* This enum covers all system catalogs whose OIDs can appear in classid. */
|
||||||
typedef enum ObjectClasses
|
typedef enum ObjectClasses
|
||||||
{
|
{
|
||||||
|
OCLASS_CAST, /* pg_cast */
|
||||||
OCLASS_CLASS, /* pg_class */
|
OCLASS_CLASS, /* pg_class */
|
||||||
OCLASS_PROC, /* pg_proc */
|
OCLASS_PROC, /* pg_proc */
|
||||||
OCLASS_TYPE, /* pg_type */
|
OCLASS_TYPE, /* pg_type */
|
||||||
@ -604,6 +605,10 @@ doDeletion(const ObjectAddress *object)
|
|||||||
RemoveSchemaById(object->objectId);
|
RemoveSchemaById(object->objectId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OCLASS_CAST:
|
||||||
|
DropCastById(object->objectId);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "doDeletion: Unsupported object class %u",
|
elog(ERROR, "doDeletion: Unsupported object class %u",
|
||||||
object->classId);
|
object->classId);
|
||||||
@ -979,6 +984,7 @@ term_object_addresses(ObjectAddresses *addrs)
|
|||||||
static void
|
static void
|
||||||
init_object_classes(void)
|
init_object_classes(void)
|
||||||
{
|
{
|
||||||
|
object_classes[OCLASS_CAST] = get_system_catalog_relid(CastRelationName);
|
||||||
object_classes[OCLASS_CLASS] = RelOid_pg_class;
|
object_classes[OCLASS_CLASS] = RelOid_pg_class;
|
||||||
object_classes[OCLASS_PROC] = RelOid_pg_proc;
|
object_classes[OCLASS_PROC] = RelOid_pg_proc;
|
||||||
object_classes[OCLASS_TYPE] = RelOid_pg_type;
|
object_classes[OCLASS_TYPE] = RelOid_pg_type;
|
||||||
@ -1023,6 +1029,11 @@ getObjectClass(const ObjectAddress *object)
|
|||||||
if (!object_classes_initialized)
|
if (!object_classes_initialized)
|
||||||
init_object_classes();
|
init_object_classes();
|
||||||
|
|
||||||
|
if (object->classId == object_classes[OCLASS_CAST])
|
||||||
|
{
|
||||||
|
Assert(object->objectSubId == 0);
|
||||||
|
return OCLASS_CAST;
|
||||||
|
}
|
||||||
if (object->classId == object_classes[OCLASS_CONSTRAINT])
|
if (object->classId == object_classes[OCLASS_CONSTRAINT])
|
||||||
{
|
{
|
||||||
Assert(object->objectSubId == 0);
|
Assert(object->objectSubId == 0);
|
||||||
@ -1078,6 +1089,10 @@ getObjectDescription(const ObjectAddress *object)
|
|||||||
|
|
||||||
switch (getObjectClass(object))
|
switch (getObjectClass(object))
|
||||||
{
|
{
|
||||||
|
case OCLASS_CAST:
|
||||||
|
appendStringInfo(&buffer, "cast");
|
||||||
|
break;
|
||||||
|
|
||||||
case OCLASS_CLASS:
|
case OCLASS_CLASS:
|
||||||
getRelationDescription(&buffer, object->objectId);
|
getRelationDescription(&buffer, object->objectId);
|
||||||
if (object->objectSubId != 0)
|
if (object->objectSubId != 0)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.97 2002/07/15 16:33:31 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.98 2002/07/18 23:11:27 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -43,6 +43,8 @@ char *Name_pg_attr_indices[Num_pg_attr_indices] =
|
|||||||
{AttributeRelidNameIndex, AttributeRelidNumIndex};
|
{AttributeRelidNameIndex, AttributeRelidNumIndex};
|
||||||
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
|
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
|
||||||
{AttrDefaultIndex, AttrDefaultOidIndex};
|
{AttrDefaultIndex, AttrDefaultOidIndex};
|
||||||
|
char *Name_pg_cast_indices[Num_pg_cast_indices] =
|
||||||
|
{CastSourceTargetIndex};
|
||||||
char *Name_pg_class_indices[Num_pg_class_indices] =
|
char *Name_pg_class_indices[Num_pg_class_indices] =
|
||||||
{ClassNameNspIndex, ClassOidIndex};
|
{ClassNameNspIndex, ClassOidIndex};
|
||||||
char *Name_pg_constraint_indices[Num_pg_constraint_indices] =
|
char *Name_pg_constraint_indices[Num_pg_constraint_indices] =
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.50 2002/07/16 22:12:18 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.51 2002/07/18 23:11:27 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -144,7 +144,6 @@ AggregateCreate(const char *aggName,
|
|||||||
"-", /* probin */
|
"-", /* probin */
|
||||||
true, /* isAgg */
|
true, /* isAgg */
|
||||||
false, /* security invoker (currently not definable for agg) */
|
false, /* security invoker (currently not definable for agg) */
|
||||||
false, /* isImplicit */
|
|
||||||
false, /* isStrict (not needed for agg) */
|
false, /* isStrict (not needed for agg) */
|
||||||
PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */
|
PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */
|
||||||
BYTE_PCT, /* default cost values */
|
BYTE_PCT, /* default cost values */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.78 2002/07/18 16:47:23 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.79 2002/07/18 23:11:27 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -55,7 +55,6 @@ ProcedureCreate(const char *procedureName,
|
|||||||
const char *probin,
|
const char *probin,
|
||||||
bool isAgg,
|
bool isAgg,
|
||||||
bool security_definer,
|
bool security_definer,
|
||||||
bool isImplicit,
|
|
||||||
bool isStrict,
|
bool isStrict,
|
||||||
char volatility,
|
char volatility,
|
||||||
int32 byte_pct,
|
int32 byte_pct,
|
||||||
@ -163,7 +162,7 @@ ProcedureCreate(const char *procedureName,
|
|||||||
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
|
values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */
|
||||||
values[i++] = BoolGetDatum(isAgg); /* proisagg */
|
values[i++] = BoolGetDatum(isAgg); /* proisagg */
|
||||||
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
|
values[i++] = BoolGetDatum(security_definer); /* prosecdef */
|
||||||
values[i++] = BoolGetDatum(isImplicit); /* proimplicit */
|
values[i++] = BoolGetDatum(false); /* proimplicit */
|
||||||
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
|
values[i++] = BoolGetDatum(isStrict); /* proisstrict */
|
||||||
values[i++] = BoolGetDatum(returnsSet); /* proretset */
|
values[i++] = BoolGetDatum(returnsSet); /* proretset */
|
||||||
values[i++] = CharGetDatum(volatility); /* provolatile */
|
values[i++] = CharGetDatum(volatility); /* provolatile */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.8 2002/07/12 18:43:16 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.9 2002/07/18 23:11:27 petere Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* These routines take the parse tree and pick out the
|
* These routines take the parse tree and pick out the
|
||||||
@ -34,7 +34,9 @@
|
|||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
#include "catalog/pg_cast.h"
|
||||||
#include "catalog/pg_language.h"
|
#include "catalog/pg_language.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
@ -44,6 +46,7 @@
|
|||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
@ -171,8 +174,7 @@ compute_attributes_sql_style(const List *options,
|
|||||||
char **language,
|
char **language,
|
||||||
char *volatility_p,
|
char *volatility_p,
|
||||||
bool *strict_p,
|
bool *strict_p,
|
||||||
bool *security_definer,
|
bool *security_definer)
|
||||||
bool *implicit_cast)
|
|
||||||
{
|
{
|
||||||
const List *option;
|
const List *option;
|
||||||
DefElem *as_item = NULL;
|
DefElem *as_item = NULL;
|
||||||
@ -180,7 +182,6 @@ compute_attributes_sql_style(const List *options,
|
|||||||
DefElem *volatility_item = NULL;
|
DefElem *volatility_item = NULL;
|
||||||
DefElem *strict_item = NULL;
|
DefElem *strict_item = NULL;
|
||||||
DefElem *security_item = NULL;
|
DefElem *security_item = NULL;
|
||||||
DefElem *implicit_item = NULL;
|
|
||||||
|
|
||||||
foreach(option, options)
|
foreach(option, options)
|
||||||
{
|
{
|
||||||
@ -216,12 +217,6 @@ compute_attributes_sql_style(const List *options,
|
|||||||
elog(ERROR, "conflicting or redundant options");
|
elog(ERROR, "conflicting or redundant options");
|
||||||
security_item = defel;
|
security_item = defel;
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "implicit")==0)
|
|
||||||
{
|
|
||||||
if (implicit_item)
|
|
||||||
elog(ERROR, "conflicting or redundant options");
|
|
||||||
implicit_item = defel;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
elog(ERROR, "invalid CREATE FUNCTION option");
|
elog(ERROR, "invalid CREATE FUNCTION option");
|
||||||
}
|
}
|
||||||
@ -252,8 +247,6 @@ compute_attributes_sql_style(const List *options,
|
|||||||
*strict_p = intVal(strict_item->arg);
|
*strict_p = intVal(strict_item->arg);
|
||||||
if (security_item)
|
if (security_item)
|
||||||
*security_definer = intVal(security_item->arg);
|
*security_definer = intVal(security_item->arg);
|
||||||
if (implicit_item)
|
|
||||||
*implicit_cast = intVal(implicit_item->arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -264,10 +257,7 @@ compute_attributes_sql_style(const List *options,
|
|||||||
* These parameters supply optional information about a function.
|
* These parameters supply optional information about a function.
|
||||||
* All have defaults if not specified.
|
* All have defaults if not specified.
|
||||||
*
|
*
|
||||||
* Note: currently, only three of these parameters actually do anything:
|
* Note: currently, only two of these parameters actually do anything:
|
||||||
*
|
|
||||||
* * isImplicit means the function may be used as an implicit type
|
|
||||||
* coercion.
|
|
||||||
*
|
*
|
||||||
* * isStrict means the function should not be called when any NULL
|
* * isStrict means the function should not be called when any NULL
|
||||||
* inputs are present; instead a NULL result value should be assumed.
|
* inputs are present; instead a NULL result value should be assumed.
|
||||||
@ -284,7 +274,7 @@ static void
|
|||||||
compute_attributes_with_style(List *parameters,
|
compute_attributes_with_style(List *parameters,
|
||||||
int32 *byte_pct_p, int32 *perbyte_cpu_p,
|
int32 *byte_pct_p, int32 *perbyte_cpu_p,
|
||||||
int32 *percall_cpu_p, int32 *outin_ratio_p,
|
int32 *percall_cpu_p, int32 *outin_ratio_p,
|
||||||
bool *isImplicit_p, bool *isStrict_p,
|
bool *isStrict_p,
|
||||||
char *volatility_p)
|
char *volatility_p)
|
||||||
{
|
{
|
||||||
List *pl;
|
List *pl;
|
||||||
@ -293,9 +283,7 @@ compute_attributes_with_style(List *parameters,
|
|||||||
{
|
{
|
||||||
DefElem *param = (DefElem *) lfirst(pl);
|
DefElem *param = (DefElem *) lfirst(pl);
|
||||||
|
|
||||||
if (strcasecmp(param->defname, "implicitcoercion") == 0)
|
if (strcasecmp(param->defname, "isstrict") == 0)
|
||||||
*isImplicit_p = true;
|
|
||||||
else if (strcasecmp(param->defname, "isstrict") == 0)
|
|
||||||
*isStrict_p = true;
|
*isStrict_p = true;
|
||||||
else if (strcasecmp(param->defname, "isimmutable") == 0)
|
else if (strcasecmp(param->defname, "isimmutable") == 0)
|
||||||
*volatility_p = PROVOLATILE_IMMUTABLE;
|
*volatility_p = PROVOLATILE_IMMUTABLE;
|
||||||
@ -398,8 +386,7 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|||||||
perbyte_cpu,
|
perbyte_cpu,
|
||||||
percall_cpu,
|
percall_cpu,
|
||||||
outin_ratio;
|
outin_ratio;
|
||||||
bool isImplicit,
|
bool isStrict,
|
||||||
isStrict,
|
|
||||||
security;
|
security;
|
||||||
char volatility;
|
char volatility;
|
||||||
HeapTuple languageTuple;
|
HeapTuple languageTuple;
|
||||||
@ -420,14 +407,13 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|||||||
perbyte_cpu = PERBYTE_CPU;
|
perbyte_cpu = PERBYTE_CPU;
|
||||||
percall_cpu = PERCALL_CPU;
|
percall_cpu = PERCALL_CPU;
|
||||||
outin_ratio = OUTIN_RATIO;
|
outin_ratio = OUTIN_RATIO;
|
||||||
isImplicit = false;
|
|
||||||
isStrict = false;
|
isStrict = false;
|
||||||
security = false;
|
security = false;
|
||||||
volatility = PROVOLATILE_VOLATILE;
|
volatility = PROVOLATILE_VOLATILE;
|
||||||
|
|
||||||
/* override attributes from explicit list */
|
/* override attributes from explicit list */
|
||||||
compute_attributes_sql_style(stmt->options,
|
compute_attributes_sql_style(stmt->options,
|
||||||
&as_clause, &language, &volatility, &isStrict, &security, &isImplicit);
|
&as_clause, &language, &volatility, &isStrict, &security);
|
||||||
|
|
||||||
/* Convert language name to canonical case */
|
/* Convert language name to canonical case */
|
||||||
case_translate_language_name(language, languageName);
|
case_translate_language_name(language, languageName);
|
||||||
@ -474,8 +460,7 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|||||||
|
|
||||||
compute_attributes_with_style(stmt->withClause,
|
compute_attributes_with_style(stmt->withClause,
|
||||||
&byte_pct, &perbyte_cpu, &percall_cpu,
|
&byte_pct, &perbyte_cpu, &percall_cpu,
|
||||||
&outin_ratio, &isImplicit, &isStrict,
|
&outin_ratio, &isStrict, &volatility);
|
||||||
&volatility);
|
|
||||||
|
|
||||||
interpret_AS_clause(languageOid, languageName, as_clause,
|
interpret_AS_clause(languageOid, languageName, as_clause,
|
||||||
&prosrc_str, &probin_str);
|
&prosrc_str, &probin_str);
|
||||||
@ -517,7 +502,6 @@ CreateFunction(CreateFunctionStmt *stmt)
|
|||||||
probin_str, /* converted to text later */
|
probin_str, /* converted to text later */
|
||||||
false, /* not an aggregate */
|
false, /* not an aggregate */
|
||||||
security,
|
security,
|
||||||
isImplicit,
|
|
||||||
isStrict,
|
isStrict,
|
||||||
volatility,
|
volatility,
|
||||||
byte_pct,
|
byte_pct,
|
||||||
@ -639,3 +623,217 @@ RemoveFunctionById(Oid funcOid)
|
|||||||
heap_close(relation, RowExclusiveLock);
|
heap_close(relation, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CREATE CAST
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
CreateCast(CreateCastStmt *stmt)
|
||||||
|
{
|
||||||
|
Oid sourcetypeid;
|
||||||
|
Oid targettypeid;
|
||||||
|
Oid funcid;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Relation relation;
|
||||||
|
Form_pg_proc procstruct;
|
||||||
|
|
||||||
|
Datum values[Natts_pg_proc];
|
||||||
|
char nulls[Natts_pg_proc];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
|
sourcetypeid = LookupTypeName(stmt->sourcetype);
|
||||||
|
if (!OidIsValid(sourcetypeid))
|
||||||
|
elog(ERROR, "source data type %s does not exist",
|
||||||
|
TypeNameToString(stmt->sourcetype));
|
||||||
|
|
||||||
|
targettypeid = LookupTypeName(stmt->targettype);
|
||||||
|
if (!OidIsValid(targettypeid))
|
||||||
|
elog(ERROR, "target data type %s does not exist",
|
||||||
|
TypeNameToString(stmt->targettype));
|
||||||
|
|
||||||
|
if (sourcetypeid == targettypeid)
|
||||||
|
elog(ERROR, "source data type and target data type are the same");
|
||||||
|
|
||||||
|
relation = heap_openr(CastRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
tuple = SearchSysCache(CASTSOURCETARGET,
|
||||||
|
ObjectIdGetDatum(sourcetypeid),
|
||||||
|
ObjectIdGetDatum(targettypeid),
|
||||||
|
0, 0);
|
||||||
|
if (HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cast from data type %s to data type %s already exists",
|
||||||
|
TypeNameToString(stmt->sourcetype),
|
||||||
|
TypeNameToString(stmt->targettype));
|
||||||
|
|
||||||
|
if (stmt->func != NULL)
|
||||||
|
{
|
||||||
|
funcid = LookupFuncNameTypeNames(stmt->func->funcname, stmt->func->funcargs, false, "CreateCast");
|
||||||
|
|
||||||
|
if(!pg_proc_ownercheck(funcid, GetUserId()))
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
|
||||||
|
tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(funcid), 0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cache lookup of function %u failed", funcid);
|
||||||
|
|
||||||
|
procstruct = (Form_pg_proc) GETSTRUCT(tuple);
|
||||||
|
if (procstruct->pronargs != 1)
|
||||||
|
elog(ERROR, "cast function must take 1 argument");
|
||||||
|
if (procstruct->proargtypes[0] != sourcetypeid)
|
||||||
|
elog(ERROR, "argument of cast function must match source data type");
|
||||||
|
if (procstruct->prorettype != targettypeid)
|
||||||
|
elog(ERROR, "return data type of cast function must match target data type");
|
||||||
|
if (procstruct->provolatile != PROVOLATILE_IMMUTABLE)
|
||||||
|
elog(ERROR, "cast function must be immutable");
|
||||||
|
if (procstruct->proisagg)
|
||||||
|
elog(ERROR, "cast function must not be an aggregate function");
|
||||||
|
if (procstruct->proretset)
|
||||||
|
elog(ERROR, "cast function must be not return a set");
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* indicates binary compatibility */
|
||||||
|
if (!pg_type_ownercheck(sourcetypeid, GetUserId())
|
||||||
|
|| !pg_type_ownercheck(targettypeid, GetUserId()))
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
funcid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ready to go */
|
||||||
|
values[Anum_pg_cast_castsource-1] = ObjectIdGetDatum(sourcetypeid);
|
||||||
|
values[Anum_pg_cast_casttarget-1] = ObjectIdGetDatum(targettypeid);
|
||||||
|
values[Anum_pg_cast_castfunc-1] = ObjectIdGetDatum(funcid);
|
||||||
|
values[Anum_pg_cast_castimplicit-1] = BoolGetDatum(stmt->implicit);
|
||||||
|
|
||||||
|
for (i = 0; i < Natts_pg_cast; ++i)
|
||||||
|
nulls[i] = ' ';
|
||||||
|
|
||||||
|
tuple = heap_formtuple(RelationGetDescr(relation), values, nulls);
|
||||||
|
simple_heap_insert(relation, tuple);
|
||||||
|
|
||||||
|
if (RelationGetForm(relation)->relhasindex)
|
||||||
|
{
|
||||||
|
Relation idescs[Num_pg_cast_indices];
|
||||||
|
|
||||||
|
CatalogOpenIndices(Num_pg_cast_indices, Name_pg_cast_indices, idescs);
|
||||||
|
CatalogIndexInsert(idescs, Num_pg_cast_indices, relation, tuple);
|
||||||
|
CatalogCloseIndices(Num_pg_cast_indices, idescs);
|
||||||
|
}
|
||||||
|
|
||||||
|
myself.classId = get_system_catalog_relid(CastRelationName);
|
||||||
|
myself.objectId = tuple->t_data->t_oid;
|
||||||
|
myself.objectSubId = 0;
|
||||||
|
|
||||||
|
/* dependency on source type */
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = sourcetypeid;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
|
||||||
|
/* dependency on target type */
|
||||||
|
referenced.classId = RelOid_pg_type;
|
||||||
|
referenced.objectId = targettypeid;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
|
||||||
|
/* dependency on function */
|
||||||
|
if (OidIsValid(funcid))
|
||||||
|
{
|
||||||
|
referenced.classId = RelOid_pg_proc;
|
||||||
|
referenced.objectId = funcid;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_freetuple(tuple);
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DROP CAST
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
DropCast(DropCastStmt *stmt)
|
||||||
|
{
|
||||||
|
Oid sourcetypeid;
|
||||||
|
Oid targettypeid;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Form_pg_cast caststruct;
|
||||||
|
ObjectAddress object;
|
||||||
|
|
||||||
|
sourcetypeid = LookupTypeName(stmt->sourcetype);
|
||||||
|
if (!OidIsValid(sourcetypeid))
|
||||||
|
elog(ERROR, "source data type %s does not exist",
|
||||||
|
TypeNameToString(stmt->sourcetype));
|
||||||
|
|
||||||
|
targettypeid = LookupTypeName(stmt->targettype);
|
||||||
|
if (!OidIsValid(targettypeid))
|
||||||
|
elog(ERROR, "target data type %s does not exist",
|
||||||
|
TypeNameToString(stmt->targettype));
|
||||||
|
|
||||||
|
tuple = SearchSysCache(CASTSOURCETARGET,
|
||||||
|
ObjectIdGetDatum(sourcetypeid),
|
||||||
|
ObjectIdGetDatum(targettypeid),
|
||||||
|
0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cast from type %s to type %s does not exist",
|
||||||
|
TypeNameToString(stmt->sourcetype),
|
||||||
|
TypeNameToString(stmt->targettype));
|
||||||
|
|
||||||
|
/* Permission check */
|
||||||
|
caststruct = (Form_pg_cast) GETSTRUCT(tuple);
|
||||||
|
if (caststruct->castfunc != InvalidOid)
|
||||||
|
{
|
||||||
|
if(!pg_proc_ownercheck(caststruct->castfunc, GetUserId()))
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!pg_type_ownercheck(sourcetypeid, GetUserId())
|
||||||
|
|| !pg_type_ownercheck(targettypeid, GetUserId()))
|
||||||
|
elog(ERROR, "permission denied");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the deletion
|
||||||
|
*/
|
||||||
|
object.classId = get_system_catalog_relid(CastRelationName);
|
||||||
|
object.objectId = tuple->t_data->t_oid;
|
||||||
|
object.objectSubId = 0;
|
||||||
|
|
||||||
|
performDeletion(&object, stmt->behavior);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DropCastById(Oid castOid)
|
||||||
|
{
|
||||||
|
Relation relation;
|
||||||
|
ScanKeyData scankey;
|
||||||
|
HeapScanDesc scan;
|
||||||
|
HeapTuple tuple;
|
||||||
|
|
||||||
|
relation = heap_openr(CastRelationName, RowExclusiveLock);
|
||||||
|
ScanKeyEntryInitialize(&scankey, 0x0,
|
||||||
|
ObjectIdAttributeNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(castOid));
|
||||||
|
scan = heap_beginscan(relation, SnapshotNow, 1, &scankey);
|
||||||
|
tuple = heap_getnext(scan, ForwardScanDirection);
|
||||||
|
if (HeapTupleIsValid(tuple))
|
||||||
|
simple_heap_delete(relation, &tuple->t_self);
|
||||||
|
else
|
||||||
|
elog(ERROR, "could not find tuple for cast %u", castOid);
|
||||||
|
heap_endscan(scan);
|
||||||
|
heap_close(relation, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.346 2002/07/18 17:14:19 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.347 2002/07/18 23:11:27 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -135,13 +135,13 @@ static void doNegateFloat(Value *v);
|
|||||||
AlterDatabaseSetStmt, AlterGroupStmt,
|
AlterDatabaseSetStmt, AlterGroupStmt,
|
||||||
AlterTableStmt, AlterUserStmt, AlterUserSetStmt,
|
AlterTableStmt, AlterUserStmt, AlterUserSetStmt,
|
||||||
AnalyzeStmt, ClosePortalStmt, ClusterStmt, CommentStmt,
|
AnalyzeStmt, ClosePortalStmt, ClusterStmt, CommentStmt,
|
||||||
ConstraintsSetStmt, CopyStmt, CreateAsStmt,
|
ConstraintsSetStmt, CopyStmt, CreateAsStmt, CreateCastStmt,
|
||||||
CreateDomainStmt, CreateGroupStmt, CreatePLangStmt,
|
CreateDomainStmt, CreateGroupStmt, CreatePLangStmt,
|
||||||
CreateSchemaStmt, CreateSeqStmt, CreateStmt,
|
CreateSchemaStmt, CreateSeqStmt, CreateStmt,
|
||||||
CreateAssertStmt, CreateTrigStmt, CreateUserStmt,
|
CreateAssertStmt, CreateTrigStmt, CreateUserStmt,
|
||||||
CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
|
CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
|
||||||
DropGroupStmt, DropPLangStmt, DropStmt,
|
DropGroupStmt, DropPLangStmt, DropStmt,
|
||||||
DropAssertStmt, DropTrigStmt, DropRuleStmt,
|
DropAssertStmt, DropTrigStmt, DropRuleStmt, DropCastStmt,
|
||||||
DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
|
DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
|
||||||
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt,
|
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt,
|
||||||
LockStmt, NotifyStmt, OptimizableStmt,
|
LockStmt, NotifyStmt, OptimizableStmt,
|
||||||
@ -165,7 +165,7 @@ static void doNegateFloat(Value *v);
|
|||||||
%type <defelt> createdb_opt_item, copy_opt_item
|
%type <defelt> createdb_opt_item, copy_opt_item
|
||||||
|
|
||||||
%type <ival> opt_lock, lock_type
|
%type <ival> opt_lock, lock_type
|
||||||
%type <boolean> opt_force, opt_or_replace
|
%type <boolean> opt_force, opt_or_replace, opt_assignment
|
||||||
|
|
||||||
%type <list> user_list
|
%type <list> user_list
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ static void doNegateFloat(Value *v);
|
|||||||
|
|
||||||
HANDLER, HAVING, HOUR_P,
|
HANDLER, HAVING, HOUR_P,
|
||||||
|
|
||||||
ILIKE, IMMEDIATE, IMMUTABLE, IMPLICIT, IN_P, INCREMENT,
|
ILIKE, IMMEDIATE, IMMUTABLE, IN_P, INCREMENT,
|
||||||
INDEX, INHERITS, INITIALLY, INNER_P, INOUT, INPUT,
|
INDEX, INHERITS, INITIALLY, INNER_P, INOUT, INPUT,
|
||||||
INSENSITIVE, INSERT, INSTEAD, INT, INTEGER, INTERSECT,
|
INSENSITIVE, INSERT, INSTEAD, INT, INTEGER, INTERSECT,
|
||||||
INTERVAL, INTO, INVOKER, IS, ISNULL, ISOLATION,
|
INTERVAL, INTO, INVOKER, IS, ISNULL, ISOLATION,
|
||||||
@ -475,6 +475,7 @@ stmt :
|
|||||||
| CopyStmt
|
| CopyStmt
|
||||||
| CreateStmt
|
| CreateStmt
|
||||||
| CreateAsStmt
|
| CreateAsStmt
|
||||||
|
| CreateCastStmt
|
||||||
| CreateDomainStmt
|
| CreateDomainStmt
|
||||||
| CreateFunctionStmt
|
| CreateFunctionStmt
|
||||||
| CreateSchemaStmt
|
| CreateSchemaStmt
|
||||||
@ -489,6 +490,7 @@ stmt :
|
|||||||
| DropStmt
|
| DropStmt
|
||||||
| TruncateStmt
|
| TruncateStmt
|
||||||
| CommentStmt
|
| CommentStmt
|
||||||
|
| DropCastStmt
|
||||||
| DropGroupStmt
|
| DropGroupStmt
|
||||||
| DropPLangStmt
|
| DropPLangStmt
|
||||||
| DropAssertStmt
|
| DropAssertStmt
|
||||||
@ -2886,15 +2888,6 @@ RecipeStmt: EXECUTE RECIPE recipe_name
|
|||||||
* as <filename or code in language as appropriate>
|
* as <filename or code in language as appropriate>
|
||||||
* language <lang> [with parameters]
|
* language <lang> [with parameters]
|
||||||
*
|
*
|
||||||
* CAST() form allowing all options from the CREATE FUNCTION form:
|
|
||||||
* create [or replace] cast (<type> as <type>)
|
|
||||||
* as <filename or code in language as appropriate>
|
|
||||||
* language <lang> [with parameters]
|
|
||||||
*
|
|
||||||
* SQL99 CAST() form (requires a function to be previously defined):
|
|
||||||
* create [or replace] cast (<type> as <type>)
|
|
||||||
* with function fname (<type>) [as assignment]
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
CreateFunctionStmt:
|
CreateFunctionStmt:
|
||||||
@ -2910,63 +2903,6 @@ CreateFunctionStmt:
|
|||||||
n->withClause = $9;
|
n->withClause = $9;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
/* CREATE CAST SQL99 standard form */
|
|
||||||
| CREATE opt_or_replace CAST '(' func_type AS func_type ')'
|
|
||||||
WITH FUNCTION func_name func_args opt_assignment opt_definition
|
|
||||||
{
|
|
||||||
CreateFunctionStmt *n;
|
|
||||||
char buf[256];
|
|
||||||
n = makeNode(CreateFunctionStmt);
|
|
||||||
n->replace = $2;
|
|
||||||
n->funcname = $7->names;
|
|
||||||
n->argTypes = makeList1($5);
|
|
||||||
n->returnType = $7;
|
|
||||||
/* expand this into a string of SQL language */
|
|
||||||
strcpy(buf, "select ");
|
|
||||||
strcat(buf, ((Value *)lfirst($11))->val.str);
|
|
||||||
strcat(buf, "($1)");
|
|
||||||
n->options = lappend($14, makeDefElem("as", (Node *)makeList1(makeString(pstrdup(buf)))));
|
|
||||||
/* make sure that this will allow implicit casting */
|
|
||||||
n->options = lappend(n->options,
|
|
||||||
makeDefElem("implicit", (Node *)makeInteger(TRUE)));
|
|
||||||
/* and mention that this is SQL language */
|
|
||||||
n->options = lappend(n->options,
|
|
||||||
makeDefElem("language", (Node *)makeString(pstrdup("sql"))));
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
/* CREATE CAST SQL99 minimally variant form */
|
|
||||||
| CREATE opt_or_replace CAST '(' func_type AS func_type ')'
|
|
||||||
WITH FUNCTION func_name func_args AS Sconst opt_definition
|
|
||||||
{
|
|
||||||
CreateFunctionStmt *n;
|
|
||||||
n = makeNode(CreateFunctionStmt);
|
|
||||||
n->replace = $2;
|
|
||||||
n->funcname = $7->names;
|
|
||||||
n->argTypes = makeList1($5);
|
|
||||||
n->returnType = $7;
|
|
||||||
n->options = lappend($15, makeDefElem("as", (Node *)lcons(makeList1(makeString($14)), $11)));
|
|
||||||
/* make sure that this will allow implicit casting */
|
|
||||||
n->options = lappend(n->options,
|
|
||||||
makeDefElem("implicit", (Node *)makeInteger(TRUE)));
|
|
||||||
n->options = lappend(n->options,
|
|
||||||
makeDefElem("language", (Node *)makeString(pstrdup("c"))));
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
/* CREATE CAST with mostly CREATE FUNCTION clauses */
|
|
||||||
| CREATE opt_or_replace CAST '(' func_type AS func_type ')'
|
|
||||||
createfunc_opt_list opt_definition
|
|
||||||
{
|
|
||||||
CreateFunctionStmt *n;
|
|
||||||
n = makeNode(CreateFunctionStmt);
|
|
||||||
n->replace = $2;
|
|
||||||
n->funcname = $7->names;
|
|
||||||
n->argTypes = makeList1($5);
|
|
||||||
n->returnType = $7;
|
|
||||||
/* make sure that this will allow implicit casting */
|
|
||||||
n->options = lappend($9, makeDefElem("implicit", (Node *)makeInteger(TRUE)));
|
|
||||||
n->withClause = $10;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_or_replace:
|
opt_or_replace:
|
||||||
@ -3090,10 +3026,6 @@ createfunc_opt_item:
|
|||||||
{
|
{
|
||||||
$$ = makeDefElem("security", (Node *)makeInteger(FALSE));
|
$$ = makeDefElem("security", (Node *)makeInteger(FALSE));
|
||||||
}
|
}
|
||||||
| IMPLICIT CAST
|
|
||||||
{
|
|
||||||
$$ = makeDefElem("implicit", (Node *)makeInteger(TRUE));
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
func_as: Sconst { $$ = makeList1(makeString($1)); }
|
func_as: Sconst { $$ = makeList1(makeString($1)); }
|
||||||
@ -3108,10 +3040,6 @@ opt_definition:
|
|||||||
| /*EMPTY*/ { $$ = NIL; }
|
| /*EMPTY*/ { $$ = NIL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_assignment: AS ASSIGNMENT {}
|
|
||||||
| /*EMPTY*/ {}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
@ -3132,14 +3060,6 @@ RemoveFuncStmt:
|
|||||||
n->behavior = $5;
|
n->behavior = $5;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| DROP CAST '(' func_type AS func_type ')' opt_drop_behavior
|
|
||||||
{
|
|
||||||
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
|
|
||||||
n->funcname = $6->names;
|
|
||||||
n->args = makeList1($4);
|
|
||||||
n->behavior = $8;
|
|
||||||
$$ = (Node *)n;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
RemoveAggrStmt:
|
RemoveAggrStmt:
|
||||||
@ -3190,6 +3110,49 @@ any_operator:
|
|||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* CREATE CAST / DROP CAST
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
CreateCastStmt: CREATE CAST '(' ConstTypename AS ConstTypename ')'
|
||||||
|
WITH FUNCTION function_with_argtypes opt_assignment
|
||||||
|
{
|
||||||
|
CreateCastStmt *n = makeNode(CreateCastStmt);
|
||||||
|
n->sourcetype = $4;
|
||||||
|
n->targettype = $6;
|
||||||
|
n->func = (FuncWithArgs *) $10;
|
||||||
|
n->implicit = $11;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| CREATE CAST '(' ConstTypename AS ConstTypename ')'
|
||||||
|
WITHOUT FUNCTION opt_assignment
|
||||||
|
{
|
||||||
|
CreateCastStmt *n = makeNode(CreateCastStmt);
|
||||||
|
n->sourcetype = $4;
|
||||||
|
n->targettype = $6;
|
||||||
|
n->func = NULL;
|
||||||
|
n->implicit = $10;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_assignment: AS ASSIGNMENT { $$ = TRUE; }
|
||||||
|
| /*EMPTY*/ { $$ = FALSE; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
DropCastStmt: DROP CAST '(' ConstTypename AS ConstTypename ')' opt_drop_behavior
|
||||||
|
{
|
||||||
|
DropCastStmt *n = makeNode(DropCastStmt);
|
||||||
|
n->sourcetype = $4;
|
||||||
|
n->targettype = $6;
|
||||||
|
n->behavior = $8;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* QUERY:
|
* QUERY:
|
||||||
@ -6701,7 +6664,6 @@ unreserved_keyword:
|
|||||||
| HOUR_P
|
| HOUR_P
|
||||||
| IMMEDIATE
|
| IMMEDIATE
|
||||||
| IMMUTABLE
|
| IMMUTABLE
|
||||||
| IMPLICIT
|
|
||||||
| INCREMENT
|
| INCREMENT
|
||||||
| INDEX
|
| INDEX
|
||||||
| INHERITS
|
| INHERITS
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.121 2002/07/18 17:14:19 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.122 2002/07/18 23:11:28 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -142,7 +142,6 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"ilike", ILIKE},
|
{"ilike", ILIKE},
|
||||||
{"immediate", IMMEDIATE},
|
{"immediate", IMMEDIATE},
|
||||||
{"immutable", IMMUTABLE},
|
{"immutable", IMMUTABLE},
|
||||||
{"implicit", IMPLICIT},
|
|
||||||
{"in", IN_P},
|
{"in", IN_P},
|
||||||
{"increment", INCREMENT},
|
{"increment", INCREMENT},
|
||||||
{"index", INDEX},
|
{"index", INDEX},
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.77 2002/07/09 13:52:14 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.78 2002/07/18 23:11:28 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "catalog/pg_cast.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
@ -31,8 +32,9 @@ Oid PromoteTypeToNext(Oid inType);
|
|||||||
|
|
||||||
static Oid PreferredType(CATEGORY category, Oid type);
|
static Oid PreferredType(CATEGORY category, Oid type);
|
||||||
static Node *build_func_call(Oid funcid, Oid rettype, List *args);
|
static Node *build_func_call(Oid funcid, Oid rettype, List *args);
|
||||||
static Oid find_coercion_function(Oid targetTypeId, Oid inputTypeId,
|
static Oid find_coercion_function(Oid targetTypeId, Oid sourceTypeId,
|
||||||
Oid secondArgType, bool isExplicit);
|
bool isExplicit);
|
||||||
|
static Oid find_typmod_coercion_function(Oid typeId);
|
||||||
static Node *TypeConstraints(Node *arg, Oid typeId);
|
static Node *TypeConstraints(Node *arg, Oid typeId);
|
||||||
|
|
||||||
/* coerce_type()
|
/* coerce_type()
|
||||||
@ -142,7 +144,6 @@ coerce_type(ParseState *pstate, Node *node, Oid inputTypeId,
|
|||||||
|
|
||||||
funcId = find_coercion_function(baseTypeId,
|
funcId = find_coercion_function(baseTypeId,
|
||||||
getBaseType(inputTypeId),
|
getBaseType(inputTypeId),
|
||||||
InvalidOid,
|
|
||||||
isExplicit);
|
isExplicit);
|
||||||
if (!OidIsValid(funcId))
|
if (!OidIsValid(funcId))
|
||||||
elog(ERROR, "coerce_type: no conversion function from '%s' to '%s'",
|
elog(ERROR, "coerce_type: no conversion function from '%s' to '%s'",
|
||||||
@ -258,7 +259,6 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids,
|
|||||||
*/
|
*/
|
||||||
funcId = find_coercion_function(getBaseType(targetTypeId),
|
funcId = find_coercion_function(getBaseType(targetTypeId),
|
||||||
getBaseType(inputTypeId),
|
getBaseType(inputTypeId),
|
||||||
InvalidOid,
|
|
||||||
isExplicit);
|
isExplicit);
|
||||||
if (!OidIsValid(funcId))
|
if (!OidIsValid(funcId))
|
||||||
return false;
|
return false;
|
||||||
@ -312,8 +312,7 @@ coerce_type_typmod(ParseState *pstate, Node *node,
|
|||||||
if (atttypmod < 0 || atttypmod == exprTypmod(node))
|
if (atttypmod < 0 || atttypmod == exprTypmod(node))
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
/* Note this is always implicit coercion */
|
funcId = find_typmod_coercion_function(baseTypeId);
|
||||||
funcId = find_coercion_function(baseTypeId, baseTypeId, INT4OID, false);
|
|
||||||
if (OidIsValid(funcId))
|
if (OidIsValid(funcId))
|
||||||
{
|
{
|
||||||
Const *cons;
|
Const *cons;
|
||||||
@ -621,21 +620,25 @@ TypeCategory(Oid inType)
|
|||||||
static bool
|
static bool
|
||||||
DirectlyBinaryCompatible(Oid type1, Oid type2)
|
DirectlyBinaryCompatible(Oid type1, Oid type2)
|
||||||
{
|
{
|
||||||
|
HeapTuple tuple;
|
||||||
|
bool result;
|
||||||
|
|
||||||
if (type1 == type2)
|
if (type1 == type2)
|
||||||
return true;
|
return true;
|
||||||
if (TypeIsTextGroup(type1) && TypeIsTextGroup(type2))
|
|
||||||
return true;
|
tuple = SearchSysCache(CASTSOURCETARGET, type1, type2, 0, 0);
|
||||||
if (TypeIsInt4GroupA(type1) && TypeIsInt4GroupA(type2))
|
if (HeapTupleIsValid(tuple))
|
||||||
return true;
|
{
|
||||||
if (TypeIsInt4GroupB(type1) && TypeIsInt4GroupB(type2))
|
Form_pg_cast caststruct;
|
||||||
return true;
|
|
||||||
if (TypeIsInt4GroupC(type1) && TypeIsInt4GroupC(type2))
|
caststruct = (Form_pg_cast) GETSTRUCT(tuple);
|
||||||
return true;
|
result = caststruct->castfunc == InvalidOid && caststruct->castimplicit;
|
||||||
if (TypeIsInetGroup(type1) && TypeIsInetGroup(type2))
|
ReleaseSysCache(tuple);
|
||||||
return true;
|
}
|
||||||
if (TypeIsBitGroup(type1) && TypeIsBitGroup(type2))
|
else
|
||||||
return true;
|
result = false;
|
||||||
return false;
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -750,34 +753,51 @@ PreferredType(CATEGORY category, Oid type)
|
|||||||
* If a function is found, return its pg_proc OID; else return InvalidOid.
|
* If a function is found, return its pg_proc OID; else return InvalidOid.
|
||||||
*/
|
*/
|
||||||
static Oid
|
static Oid
|
||||||
find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType,
|
find_coercion_function(Oid targetTypeId, Oid sourceTypeId, bool isExplicit)
|
||||||
bool isExplicit)
|
{
|
||||||
|
Oid funcid = InvalidOid;
|
||||||
|
HeapTuple tuple;
|
||||||
|
|
||||||
|
tuple = SearchSysCache(CASTSOURCETARGET,
|
||||||
|
ObjectIdGetDatum(sourceTypeId),
|
||||||
|
ObjectIdGetDatum(targetTypeId),
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
if (HeapTupleIsValid(tuple))
|
||||||
|
{
|
||||||
|
Form_pg_cast cform = (Form_pg_cast) GETSTRUCT(tuple);
|
||||||
|
|
||||||
|
if (isExplicit || cform->castimplicit)
|
||||||
|
funcid = cform->castfunc;
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
}
|
||||||
|
|
||||||
|
return funcid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Oid
|
||||||
|
find_typmod_coercion_function(Oid typeId)
|
||||||
{
|
{
|
||||||
Oid funcid = InvalidOid;
|
Oid funcid = InvalidOid;
|
||||||
Type targetType;
|
Type targetType;
|
||||||
char *typname;
|
char *typname;
|
||||||
Oid typnamespace;
|
Oid typnamespace;
|
||||||
Oid oid_array[FUNC_MAX_ARGS];
|
Oid oid_array[FUNC_MAX_ARGS];
|
||||||
int nargs;
|
|
||||||
HeapTuple ftup;
|
HeapTuple ftup;
|
||||||
|
|
||||||
targetType = typeidType(targetTypeId);
|
targetType = typeidType(typeId);
|
||||||
typname = NameStr(((Form_pg_type) GETSTRUCT(targetType))->typname);
|
typname = NameStr(((Form_pg_type) GETSTRUCT(targetType))->typname);
|
||||||
typnamespace = ((Form_pg_type) GETSTRUCT(targetType))->typnamespace;
|
typnamespace = ((Form_pg_type) GETSTRUCT(targetType))->typnamespace;
|
||||||
|
|
||||||
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
|
||||||
oid_array[0] = inputTypeId;
|
oid_array[0] = typeId;
|
||||||
if (OidIsValid(secondArgType))
|
oid_array[1] = INT4OID;
|
||||||
{
|
|
||||||
oid_array[1] = secondArgType;
|
|
||||||
nargs = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nargs = 1;
|
|
||||||
|
|
||||||
ftup = SearchSysCache(PROCNAMENSP,
|
ftup = SearchSysCache(PROCNAMENSP,
|
||||||
CStringGetDatum(typname),
|
CStringGetDatum(typname),
|
||||||
Int16GetDatum(nargs),
|
Int16GetDatum(2),
|
||||||
PointerGetDatum(oid_array),
|
PointerGetDatum(oid_array),
|
||||||
ObjectIdGetDatum(typnamespace));
|
ObjectIdGetDatum(typnamespace));
|
||||||
if (HeapTupleIsValid(ftup))
|
if (HeapTupleIsValid(ftup))
|
||||||
@ -785,16 +805,12 @@ find_coercion_function(Oid targetTypeId, Oid inputTypeId, Oid secondArgType,
|
|||||||
Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
|
Form_pg_proc pform = (Form_pg_proc) GETSTRUCT(ftup);
|
||||||
|
|
||||||
/* Make sure the function's result type is as expected */
|
/* Make sure the function's result type is as expected */
|
||||||
if (pform->prorettype == targetTypeId && !pform->proretset &&
|
if (pform->prorettype == typeId && !pform->proretset &&
|
||||||
!pform->proisagg)
|
!pform->proisagg)
|
||||||
{
|
|
||||||
/* If needed, make sure it can be invoked implicitly */
|
|
||||||
if (isExplicit || pform->proimplicit)
|
|
||||||
{
|
{
|
||||||
/* Okay to use it */
|
/* Okay to use it */
|
||||||
funcid = ftup->t_data->t_oid;
|
funcid = ftup->t_data->t_oid;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ReleaseSysCache(ftup);
|
ReleaseSysCache(ftup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.271 2002/07/18 16:47:25 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.272 2002/07/18 23:11:28 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* this is the "main" module of the postgres backend and
|
* this is the "main" module of the postgres backend and
|
||||||
@ -1693,7 +1693,7 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
if (!IsUnderPostmaster)
|
if (!IsUnderPostmaster)
|
||||||
{
|
{
|
||||||
puts("\nPOSTGRES backend interactive interface ");
|
puts("\nPOSTGRES backend interactive interface ");
|
||||||
puts("$Revision: 1.271 $ $Date: 2002/07/18 16:47:25 $\n");
|
puts("$Revision: 1.272 $ $Date: 2002/07/18 23:11:28 $\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2444,6 +2444,14 @@ CreateCommandTag(Node *parsetree)
|
|||||||
tag = "CREATE CONVERSION";
|
tag = "CREATE CONVERSION";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_CreateCastStmt:
|
||||||
|
tag = "CREATE CAST";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_DropCastStmt:
|
||||||
|
tag = "DROP CAST";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(LOG, "CreateCommandTag: unknown parse node type %d",
|
elog(LOG, "CreateCommandTag: unknown parse node type %d",
|
||||||
nodeTag(parsetree));
|
nodeTag(parsetree));
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.163 2002/07/18 16:47:25 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.164 2002/07/18 23:11:28 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -829,6 +829,14 @@ ProcessUtility(Node *parsetree,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_CreateCastStmt:
|
||||||
|
CreateCast((CreateCastStmt *) parsetree);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_DropCastStmt:
|
||||||
|
DropCast((DropCastStmt *) parsetree);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "ProcessUtility: command #%d unsupported",
|
elog(ERROR, "ProcessUtility: command #%d unsupported",
|
||||||
nodeTag(parsetree));
|
nodeTag(parsetree));
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.111 2002/07/18 17:14:20 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.112 2002/07/18 23:11:28 petere Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -43,6 +43,7 @@
|
|||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
|
#include "catalog/pg_cast.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
@ -2048,9 +2049,9 @@ get_agg_expr(Aggref *aggref, deparse_context *context)
|
|||||||
* Strip any type coercions at the top of the given expression tree,
|
* Strip any type coercions at the top of the given expression tree,
|
||||||
* as long as they are coercions to the given datatype.
|
* as long as they are coercions to the given datatype.
|
||||||
*
|
*
|
||||||
* A RelabelType node is always a type coercion. A function call is also
|
* A RelabelType node is always a type coercion. A function call is
|
||||||
* considered a type coercion if it has one argument and the function name
|
* also considered a type coercion if it has one argument and there is
|
||||||
* is the same as the (internal) name of its result type.
|
* a cast declared that uses it.
|
||||||
*
|
*
|
||||||
* XXX It'd be better if the parsetree retained some explicit indication
|
* XXX It'd be better if the parsetree retained some explicit indication
|
||||||
* of the coercion, so we didn't need these heuristics.
|
* of the coercion, so we didn't need these heuristics.
|
||||||
@ -2069,9 +2070,9 @@ strip_type_coercion(Node *expr, Oid resultType)
|
|||||||
{
|
{
|
||||||
Func *func;
|
Func *func;
|
||||||
HeapTuple procTuple;
|
HeapTuple procTuple;
|
||||||
HeapTuple typeTuple;
|
HeapTuple castTuple;
|
||||||
Form_pg_proc procStruct;
|
Form_pg_proc procStruct;
|
||||||
Form_pg_type typeStruct;
|
Form_pg_cast castStruct;
|
||||||
|
|
||||||
func = (Func *) (((Expr *) expr)->oper);
|
func = (Func *) (((Expr *) expr)->oper);
|
||||||
Assert(IsA(func, Func));
|
Assert(IsA(func, Func));
|
||||||
@ -2085,33 +2086,33 @@ strip_type_coercion(Node *expr, Oid resultType)
|
|||||||
elog(ERROR, "cache lookup for proc %u failed", func->funcid);
|
elog(ERROR, "cache lookup for proc %u failed", func->funcid);
|
||||||
procStruct = (Form_pg_proc) GETSTRUCT(procTuple);
|
procStruct = (Form_pg_proc) GETSTRUCT(procTuple);
|
||||||
/* Double-check func has one arg and correct result type */
|
/* Double-check func has one arg and correct result type */
|
||||||
/* Also, it must be an implicit coercion function */
|
|
||||||
if (procStruct->pronargs != 1 ||
|
if (procStruct->pronargs != 1 ||
|
||||||
procStruct->prorettype != resultType ||
|
procStruct->prorettype != resultType)
|
||||||
!procStruct->proimplicit)
|
|
||||||
{
|
{
|
||||||
ReleaseSysCache(procTuple);
|
ReleaseSysCache(procTuple);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
/* See if function has same name/namespace as its result type */
|
/* See if function has is actually declared as a cast */
|
||||||
typeTuple = SearchSysCache(TYPEOID,
|
castTuple = SearchSysCache(CASTSOURCETARGET,
|
||||||
|
ObjectIdGetDatum(procStruct->proargtypes[0]),
|
||||||
ObjectIdGetDatum(procStruct->prorettype),
|
ObjectIdGetDatum(procStruct->prorettype),
|
||||||
0, 0, 0);
|
0, 0);
|
||||||
if (!HeapTupleIsValid(typeTuple))
|
if (!HeapTupleIsValid(castTuple))
|
||||||
elog(ERROR, "cache lookup for type %u failed",
|
|
||||||
procStruct->prorettype);
|
|
||||||
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
|
|
||||||
if (strcmp(NameStr(procStruct->proname),
|
|
||||||
NameStr(typeStruct->typname)) != 0 ||
|
|
||||||
procStruct->pronamespace != typeStruct->typnamespace)
|
|
||||||
{
|
{
|
||||||
ReleaseSysCache(procTuple);
|
ReleaseSysCache(procTuple);
|
||||||
ReleaseSysCache(typeTuple);
|
return expr;
|
||||||
|
}
|
||||||
|
/* It must also be an implicit cast. */
|
||||||
|
castStruct = (Form_pg_cast) GETSTRUCT(castTuple);
|
||||||
|
if (!castStruct->castimplicit)
|
||||||
|
{
|
||||||
|
ReleaseSysCache(procTuple);
|
||||||
|
ReleaseSysCache(castTuple);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
/* Okay, it is indeed a type-coercion function */
|
/* Okay, it is indeed a type-coercion function */
|
||||||
ReleaseSysCache(procTuple);
|
ReleaseSysCache(procTuple);
|
||||||
ReleaseSysCache(typeTuple);
|
ReleaseSysCache(castTuple);
|
||||||
return strip_type_coercion(lfirst(((Expr *) expr)->args), resultType);
|
return strip_type_coercion(lfirst(((Expr *) expr)->args), resultType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.46 2002/06/20 20:29:38 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.47 2002/07/18 23:11:29 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -63,7 +63,6 @@ SetDefine(char *querystr, Oid elemType)
|
|||||||
fileName, /* probin */
|
fileName, /* probin */
|
||||||
false, /* not aggregate */
|
false, /* not aggregate */
|
||||||
false, /* security invoker */
|
false, /* security invoker */
|
||||||
false, /* not implicit coercion */
|
|
||||||
false, /* isStrict (irrelevant, no args) */
|
false, /* isStrict (irrelevant, no args) */
|
||||||
PROVOLATILE_VOLATILE, /* assume unsafe */
|
PROVOLATILE_VOLATILE, /* assume unsafe */
|
||||||
100, /* byte_pct */
|
100, /* byte_pct */
|
||||||
|
14
src/backend/utils/cache/syscache.c
vendored
14
src/backend/utils/cache/syscache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.81 2002/07/11 07:39:27 ishii Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.82 2002/07/18 23:11:29 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include "catalog/pg_aggregate.h"
|
#include "catalog/pg_aggregate.h"
|
||||||
#include "catalog/pg_amop.h"
|
#include "catalog/pg_amop.h"
|
||||||
#include "catalog/pg_amproc.h"
|
#include "catalog/pg_amproc.h"
|
||||||
|
#include "catalog/pg_cast.h"
|
||||||
#include "catalog/pg_conversion.h"
|
#include "catalog/pg_conversion.h"
|
||||||
#include "catalog/pg_group.h"
|
#include "catalog/pg_group.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
@ -174,6 +175,17 @@ static const struct cachedesc cacheinfo[] = {
|
|||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
|
{
|
||||||
|
CastRelationName, /* CASTSOURCETARGET */
|
||||||
|
CastSourceTargetIndex,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
Anum_pg_cast_castsource,
|
||||||
|
Anum_pg_cast_casttarget,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
}},
|
||||||
{OperatorClassRelationName, /* CLAAMNAMENSP */
|
{OperatorClassRelationName, /* CLAAMNAMENSP */
|
||||||
OpclassAmNameNspIndex,
|
OpclassAmNameNspIndex,
|
||||||
0,
|
0,
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
# Portions Copyright (c) 1994, Regents of the University of California
|
# Portions Copyright (c) 1994, Regents of the University of California
|
||||||
#
|
#
|
||||||
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.160 2002/07/18 16:47:25 tgl Exp $
|
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.161 2002/07/18 23:11:29 petere Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -708,6 +708,7 @@ $ECHO_N "initializing pg_depend... "$ECHO_C
|
|||||||
-- First delete any already-made entries; PINs override all else, and must
|
-- First delete any already-made entries; PINs override all else, and must
|
||||||
-- be the only entries for their objects.
|
-- be the only entries for their objects.
|
||||||
DELETE FROM pg_depend;
|
DELETE FROM pg_depend;
|
||||||
|
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_cast;
|
||||||
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_class;
|
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_class;
|
||||||
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_proc;
|
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_proc;
|
||||||
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_type;
|
INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' FROM pg_type;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.65 2002/06/20 20:29:41 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.66 2002/07/18 23:11:29 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -170,6 +170,13 @@ dumpSchema(Archive *fout,
|
|||||||
dumpOprs(fout, oprinfo, numOperators);
|
dumpOprs(fout, oprinfo, numOperators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dataOnly)
|
||||||
|
{
|
||||||
|
if (g_verbose)
|
||||||
|
write_msg(NULL, "dumping out user-defined casts\n");
|
||||||
|
dumpCasts(fout, finfo, numFuncs, tinfo, numTypes);
|
||||||
|
}
|
||||||
|
|
||||||
*numTablesPtr = numTables;
|
*numTablesPtr = numTables;
|
||||||
return tblinfo;
|
return tblinfo;
|
||||||
}
|
}
|
||||||
@ -386,6 +393,23 @@ findFuncByOid(FuncInfo *finfo, int numFuncs, const char *oid)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finds the index (in tinfo) of the type with the given OID. Returns
|
||||||
|
* -1 if not found.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
findTypeByOid(TypeInfo *tinfo, int numTypes, const char *oid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < numTypes; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(tinfo[i].oid, oid) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* findOprByOid
|
* findOprByOid
|
||||||
* given the oid of an operator, return the name of the operator
|
* given the oid of an operator, return the name of the operator
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.273 2002/07/18 04:50:51 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.274 2002/07/18 23:11:29 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3398,7 +3398,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
char *prosrc;
|
char *prosrc;
|
||||||
char *probin;
|
char *probin;
|
||||||
char *provolatile;
|
char *provolatile;
|
||||||
char *proimplicit;
|
|
||||||
char *proisstrict;
|
char *proisstrict;
|
||||||
char *prosecdef;
|
char *prosecdef;
|
||||||
char *lanname;
|
char *lanname;
|
||||||
@ -3417,7 +3416,7 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
{
|
{
|
||||||
appendPQExpBuffer(query,
|
appendPQExpBuffer(query,
|
||||||
"SELECT proretset, prosrc, probin, "
|
"SELECT proretset, prosrc, probin, "
|
||||||
"provolatile, proimplicit, proisstrict, prosecdef, "
|
"provolatile, proisstrict, prosecdef, "
|
||||||
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
|
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
|
||||||
"FROM pg_catalog.pg_proc "
|
"FROM pg_catalog.pg_proc "
|
||||||
"WHERE oid = '%s'::pg_catalog.oid",
|
"WHERE oid = '%s'::pg_catalog.oid",
|
||||||
@ -3428,7 +3427,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
appendPQExpBuffer(query,
|
appendPQExpBuffer(query,
|
||||||
"SELECT proretset, prosrc, probin, "
|
"SELECT proretset, prosrc, probin, "
|
||||||
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
||||||
"'f'::boolean as proimplicit, "
|
|
||||||
"proisstrict, "
|
"proisstrict, "
|
||||||
"'f'::boolean as prosecdef, "
|
"'f'::boolean as prosecdef, "
|
||||||
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
||||||
@ -3441,7 +3439,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
appendPQExpBuffer(query,
|
appendPQExpBuffer(query,
|
||||||
"SELECT proretset, prosrc, probin, "
|
"SELECT proretset, prosrc, probin, "
|
||||||
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
"case when proiscachable then 'i' else 'v' end as provolatile, "
|
||||||
"'f'::boolean as proimplicit, "
|
|
||||||
"'f'::boolean as proisstrict, "
|
"'f'::boolean as proisstrict, "
|
||||||
"'f'::boolean as prosecdef, "
|
"'f'::boolean as prosecdef, "
|
||||||
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
||||||
@ -3472,7 +3469,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
|
prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
|
||||||
probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
|
probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
|
||||||
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
|
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
|
||||||
proimplicit = PQgetvalue(res, 0, PQfnumber(res, "proimplicit"));
|
|
||||||
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
|
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
|
||||||
prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
|
prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
|
||||||
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
|
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
|
||||||
@ -3533,9 +3529,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proimplicit[0] == 't')
|
|
||||||
appendPQExpBuffer(q, " IMPLICIT CAST");
|
|
||||||
|
|
||||||
if (proisstrict[0] == 't')
|
if (proisstrict[0] == 't')
|
||||||
appendPQExpBuffer(q, " STRICT");
|
appendPQExpBuffer(q, " STRICT");
|
||||||
|
|
||||||
@ -3569,6 +3562,108 @@ done:
|
|||||||
free(funcsig_tag);
|
free(funcsig_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump all casts
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dumpCasts(Archive *fout,
|
||||||
|
FuncInfo *finfo, int numFuncs,
|
||||||
|
TypeInfo *tinfo, int numTypes)
|
||||||
|
{
|
||||||
|
PGresult *res;
|
||||||
|
PQExpBuffer query = createPQExpBuffer();
|
||||||
|
PQExpBuffer defqry = createPQExpBuffer();
|
||||||
|
PQExpBuffer delqry = createPQExpBuffer();
|
||||||
|
int ntups;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Make sure we are in proper schema */
|
||||||
|
selectSourceSchema("pg_catalog");
|
||||||
|
|
||||||
|
if (fout->remoteVersion >= 70300)
|
||||||
|
appendPQExpBuffer(query, "SELECT oid, castsource, casttarget, castfunc, castimplicit FROM pg_cast ORDER BY 1,2,3;");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(query, "SELECT p.oid, t1.oid, t2.oid, p.oid, true FROM pg_type t1, pg_type t2, pg_proc p WHERE p.pronargs = 1 AND p.proargtypes[0] = t1.oid AND p.prorettype = t2.oid AND p.proname = t2.typname ORDER BY 1,2,3;");
|
||||||
|
|
||||||
|
res = PQexec(g_conn, query->data);
|
||||||
|
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
|
{
|
||||||
|
write_msg(NULL, "query to obtain list of casts failed: %s",
|
||||||
|
PQerrorMessage(g_conn));
|
||||||
|
exit_nicely();
|
||||||
|
}
|
||||||
|
ntups = PQntuples(res);
|
||||||
|
|
||||||
|
for (i = 0; i < ntups; i++)
|
||||||
|
{
|
||||||
|
char * castoid = PQgetvalue(res, i, 0);
|
||||||
|
char * castsource = PQgetvalue(res, i, 1);
|
||||||
|
char * casttarget = PQgetvalue(res, i, 2);
|
||||||
|
char * castfunc = PQgetvalue(res, i, 3);
|
||||||
|
char * castimplicit = PQgetvalue(res, i, 4);
|
||||||
|
int fidx = -1;
|
||||||
|
const char *((*deps)[]);
|
||||||
|
|
||||||
|
if (strcmp(castfunc, "0") != 0)
|
||||||
|
fidx = findFuncByOid(finfo, numFuncs, castfunc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We treat the cast as being in the namespace of the
|
||||||
|
* underlying function. This doesn't handle binary compatible
|
||||||
|
* casts. Where should those go?
|
||||||
|
*/
|
||||||
|
if (fidx < 0 || !finfo[fidx].pronamespace->dump)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Make a dependency to ensure function is dumped first */
|
||||||
|
if (fidx >= 0)
|
||||||
|
{
|
||||||
|
deps = malloc(sizeof(char *) * 2);
|
||||||
|
|
||||||
|
(*deps)[0] = strdup(castfunc);
|
||||||
|
(*deps)[1] = NULL; /* End of List */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
deps = NULL;
|
||||||
|
|
||||||
|
resetPQExpBuffer(defqry);
|
||||||
|
resetPQExpBuffer(delqry);
|
||||||
|
|
||||||
|
appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
|
||||||
|
getFormattedTypeName(castsource, zeroAsNone),
|
||||||
|
getFormattedTypeName(casttarget, zeroAsNone));
|
||||||
|
|
||||||
|
appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
|
||||||
|
getFormattedTypeName(castsource, zeroAsNone),
|
||||||
|
getFormattedTypeName(casttarget, zeroAsNone));
|
||||||
|
|
||||||
|
if (strcmp(castfunc, "0")==0)
|
||||||
|
appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(defqry, "WITH FUNCTION %s",
|
||||||
|
format_function_signature(&finfo[fidx], true));
|
||||||
|
|
||||||
|
if (strcmp(castimplicit, "t")==0)
|
||||||
|
appendPQExpBuffer(defqry, " AS ASSIGNMENT");
|
||||||
|
appendPQExpBuffer(defqry, ";\n");
|
||||||
|
|
||||||
|
ArchiveEntry(fout, castoid,
|
||||||
|
format_function_signature(&finfo[fidx], false),
|
||||||
|
finfo[fidx].pronamespace->nspname, "",
|
||||||
|
"CAST", deps,
|
||||||
|
defqry->data, delqry->data,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
destroyPQExpBuffer(query);
|
||||||
|
destroyPQExpBuffer(defqry);
|
||||||
|
destroyPQExpBuffer(delqry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpOprs
|
* dumpOprs
|
||||||
* writes out to fout the queries to recreate all the user-defined operators
|
* writes out to fout the queries to recreate all the user-defined operators
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_dump.h,v 1.90 2002/07/06 20:12:30 momjian Exp $
|
* $Id: pg_dump.h,v 1.91 2002/07/18 23:11:29 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -177,6 +177,7 @@ typedef enum _OidOptions
|
|||||||
extern int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid);
|
extern int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid);
|
||||||
extern char *findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid);
|
extern char *findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid);
|
||||||
extern int findFuncByOid(FuncInfo *finfo, int numFuncs, const char *oid);
|
extern int findFuncByOid(FuncInfo *finfo, int numFuncs, const char *oid);
|
||||||
|
extern int findTypeByOid(TypeInfo *tinfo, int numTypes, const char *oid);
|
||||||
|
|
||||||
extern void check_conn_and_db(void);
|
extern void check_conn_and_db(void);
|
||||||
extern void exit_nicely(void);
|
extern void exit_nicely(void);
|
||||||
@ -202,6 +203,8 @@ extern void dumpTypes(Archive *fout, FuncInfo *finfo, int numFuncs,
|
|||||||
TypeInfo *tinfo, int numTypes);
|
TypeInfo *tinfo, int numTypes);
|
||||||
extern void dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs);
|
extern void dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs);
|
||||||
extern void dumpFuncs(Archive *fout, FuncInfo finfo[], int numFuncs);
|
extern void dumpFuncs(Archive *fout, FuncInfo finfo[], int numFuncs);
|
||||||
|
extern void dumpCasts(Archive *fout, FuncInfo *finfo, int numFuncs,
|
||||||
|
TypeInfo *tinfo, int numTypes);
|
||||||
extern void dumpAggs(Archive *fout, AggInfo agginfo[], int numAggregates);
|
extern void dumpAggs(Archive *fout, AggInfo agginfo[], int numAggregates);
|
||||||
extern void dumpOprs(Archive *fout, OprInfo *oprinfo, int numOperators);
|
extern void dumpOprs(Archive *fout, OprInfo *oprinfo, int numOperators);
|
||||||
extern void dumpTables(Archive *fout, TableInfo tblinfo[], int numTables,
|
extern void dumpTables(Archive *fout, TableInfo tblinfo[], int numTables,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: catname.h,v 1.28 2002/07/12 18:43:19 tgl Exp $
|
* $Id: catname.h,v 1.29 2002/07/18 23:11:30 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#define AccessMethodOperatorRelationName "pg_amop"
|
#define AccessMethodOperatorRelationName "pg_amop"
|
||||||
#define AccessMethodProcedureRelationName "pg_amproc"
|
#define AccessMethodProcedureRelationName "pg_amproc"
|
||||||
#define AttributeRelationName "pg_attribute"
|
#define AttributeRelationName "pg_attribute"
|
||||||
|
#define CastRelationName "pg_cast"
|
||||||
#define ConstraintRelationName "pg_constraint"
|
#define ConstraintRelationName "pg_constraint"
|
||||||
#define ConversionRelationName "pg_conversion"
|
#define ConversionRelationName "pg_conversion"
|
||||||
#define DatabaseRelationName "pg_database"
|
#define DatabaseRelationName "pg_database"
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: catversion.h,v 1.140 2002/07/15 16:33:31 tgl Exp $
|
* $Id: catversion.h,v 1.141 2002/07/18 23:11:30 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200207141
|
#define CATALOG_VERSION_NO 200207191
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: indexing.h,v 1.70 2002/07/15 16:33:31 tgl Exp $
|
* $Id: indexing.h,v 1.71 2002/07/18 23:11:30 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#define Num_pg_amproc_indices 1
|
#define Num_pg_amproc_indices 1
|
||||||
#define Num_pg_attr_indices 2
|
#define Num_pg_attr_indices 2
|
||||||
#define Num_pg_attrdef_indices 2
|
#define Num_pg_attrdef_indices 2
|
||||||
|
#define Num_pg_cast_indices 1
|
||||||
#define Num_pg_class_indices 2
|
#define Num_pg_class_indices 2
|
||||||
#define Num_pg_constraint_indices 3
|
#define Num_pg_constraint_indices 3
|
||||||
#define Num_pg_conversion_indices 3
|
#define Num_pg_conversion_indices 3
|
||||||
@ -60,6 +61,7 @@
|
|||||||
#define AttrDefaultOidIndex "pg_attrdef_oid_index"
|
#define AttrDefaultOidIndex "pg_attrdef_oid_index"
|
||||||
#define AttributeRelidNameIndex "pg_attribute_relid_attnam_index"
|
#define AttributeRelidNameIndex "pg_attribute_relid_attnam_index"
|
||||||
#define AttributeRelidNumIndex "pg_attribute_relid_attnum_index"
|
#define AttributeRelidNumIndex "pg_attribute_relid_attnum_index"
|
||||||
|
#define CastSourceTargetIndex "pg_cast_source_target_index"
|
||||||
#define ClassNameNspIndex "pg_class_relname_nsp_index"
|
#define ClassNameNspIndex "pg_class_relname_nsp_index"
|
||||||
#define ClassOidIndex "pg_class_oid_index"
|
#define ClassOidIndex "pg_class_oid_index"
|
||||||
#define ConstraintNameNspIndex "pg_constraint_conname_nsp_index"
|
#define ConstraintNameNspIndex "pg_constraint_conname_nsp_index"
|
||||||
@ -108,6 +110,7 @@ extern char *Name_pg_amop_indices[];
|
|||||||
extern char *Name_pg_amproc_indices[];
|
extern char *Name_pg_amproc_indices[];
|
||||||
extern char *Name_pg_attr_indices[];
|
extern char *Name_pg_attr_indices[];
|
||||||
extern char *Name_pg_attrdef_indices[];
|
extern char *Name_pg_attrdef_indices[];
|
||||||
|
extern char *Name_pg_cast_indices[];
|
||||||
extern char *Name_pg_class_indices[];
|
extern char *Name_pg_class_indices[];
|
||||||
extern char *Name_pg_constraint_indices[];
|
extern char *Name_pg_constraint_indices[];
|
||||||
extern char *Name_pg_conversion_indices[];
|
extern char *Name_pg_conversion_indices[];
|
||||||
@ -166,6 +169,7 @@ DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(ad
|
|||||||
DECLARE_UNIQUE_INDEX(pg_attrdef_oid_index on pg_attrdef using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_attrdef_oid_index on pg_attrdef using btree(oid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
|
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
|
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
|
||||||
|
DECLARE_UNIQUE_INDEX(pg_cast_source_target_index on pg_cast using btree(castsource oid_ops, casttarget oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops));
|
||||||
DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index on pg_class using btree(relname name_ops, relnamespace oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index on pg_class using btree(relname name_ops, relnamespace oid_ops));
|
||||||
/* This following index is not used for a cache and is not unique */
|
/* This following index is not used for a cache and is not unique */
|
||||||
|
225
src/include/catalog/pg_cast.h
Normal file
225
src/include/catalog/pg_cast.h
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* $Header: /cvsroot/pgsql/src/include/catalog/pg_cast.h,v 1.1 2002/07/18 23:11:30 petere Exp $
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002, PostgreSQL Global Development Group
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef PG_CAST_H
|
||||||
|
#define PG_CAST_H
|
||||||
|
|
||||||
|
CATALOG(pg_cast)
|
||||||
|
{
|
||||||
|
Oid castsource;
|
||||||
|
Oid casttarget;
|
||||||
|
Oid castfunc; /* 0 = binary compatible */
|
||||||
|
bool castimplicit;
|
||||||
|
} FormData_pg_cast;
|
||||||
|
|
||||||
|
typedef FormData_pg_cast *Form_pg_cast;
|
||||||
|
|
||||||
|
#define Natts_pg_cast 4
|
||||||
|
#define Anum_pg_cast_castsource 1
|
||||||
|
#define Anum_pg_cast_casttarget 2
|
||||||
|
#define Anum_pg_cast_castfunc 3
|
||||||
|
#define Anum_pg_cast_castimplicit 4
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* initial contents of pg_cast
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* binary compatible casts
|
||||||
|
*/
|
||||||
|
DATA(insert ( 25 1042 0 t ));
|
||||||
|
DATA(insert ( 25 1043 0 t ));
|
||||||
|
DATA(insert ( 1042 25 0 t ));
|
||||||
|
DATA(insert ( 1042 1043 0 t ));
|
||||||
|
DATA(insert ( 1043 25 0 t ));
|
||||||
|
DATA(insert ( 1043 1042 0 t ));
|
||||||
|
|
||||||
|
DATA(insert ( 23 24 0 t ));
|
||||||
|
DATA(insert ( 23 26 0 t ));
|
||||||
|
DATA(insert ( 23 2202 0 t ));
|
||||||
|
DATA(insert ( 23 2203 0 t ));
|
||||||
|
DATA(insert ( 23 2204 0 t ));
|
||||||
|
DATA(insert ( 23 2205 0 t ));
|
||||||
|
DATA(insert ( 23 2206 0 t ));
|
||||||
|
DATA(insert ( 24 23 0 t ));
|
||||||
|
DATA(insert ( 24 26 0 t ));
|
||||||
|
DATA(insert ( 24 2202 0 t ));
|
||||||
|
DATA(insert ( 24 2203 0 t ));
|
||||||
|
DATA(insert ( 24 2204 0 t ));
|
||||||
|
DATA(insert ( 24 2205 0 t ));
|
||||||
|
DATA(insert ( 24 2206 0 t ));
|
||||||
|
DATA(insert ( 26 23 0 t ));
|
||||||
|
DATA(insert ( 26 24 0 t ));
|
||||||
|
DATA(insert ( 26 2202 0 t ));
|
||||||
|
DATA(insert ( 26 2203 0 t ));
|
||||||
|
DATA(insert ( 26 2204 0 t ));
|
||||||
|
DATA(insert ( 26 2205 0 t ));
|
||||||
|
DATA(insert ( 26 2206 0 t ));
|
||||||
|
DATA(insert ( 2202 23 0 t ));
|
||||||
|
DATA(insert ( 2202 24 0 t ));
|
||||||
|
DATA(insert ( 2202 26 0 t ));
|
||||||
|
DATA(insert ( 2202 2203 0 t ));
|
||||||
|
DATA(insert ( 2202 2204 0 t ));
|
||||||
|
DATA(insert ( 2202 2205 0 t ));
|
||||||
|
DATA(insert ( 2202 2206 0 t ));
|
||||||
|
DATA(insert ( 2203 23 0 t ));
|
||||||
|
DATA(insert ( 2203 24 0 t ));
|
||||||
|
DATA(insert ( 2203 26 0 t ));
|
||||||
|
DATA(insert ( 2203 2202 0 t ));
|
||||||
|
DATA(insert ( 2203 2204 0 t ));
|
||||||
|
DATA(insert ( 2203 2205 0 t ));
|
||||||
|
DATA(insert ( 2203 2206 0 t ));
|
||||||
|
DATA(insert ( 2204 23 0 t ));
|
||||||
|
DATA(insert ( 2204 24 0 t ));
|
||||||
|
DATA(insert ( 2204 26 0 t ));
|
||||||
|
DATA(insert ( 2204 2202 0 t ));
|
||||||
|
DATA(insert ( 2204 2203 0 t ));
|
||||||
|
DATA(insert ( 2204 2205 0 t ));
|
||||||
|
DATA(insert ( 2204 2206 0 t ));
|
||||||
|
DATA(insert ( 2205 23 0 t ));
|
||||||
|
DATA(insert ( 2205 24 0 t ));
|
||||||
|
DATA(insert ( 2205 26 0 t ));
|
||||||
|
DATA(insert ( 2205 2202 0 t ));
|
||||||
|
DATA(insert ( 2205 2203 0 t ));
|
||||||
|
DATA(insert ( 2205 2204 0 t ));
|
||||||
|
DATA(insert ( 2205 2206 0 t ));
|
||||||
|
DATA(insert ( 2206 23 0 t ));
|
||||||
|
DATA(insert ( 2206 24 0 t ));
|
||||||
|
DATA(insert ( 2206 26 0 t ));
|
||||||
|
DATA(insert ( 2206 2202 0 t ));
|
||||||
|
DATA(insert ( 2206 2203 0 t ));
|
||||||
|
DATA(insert ( 2206 2204 0 t ));
|
||||||
|
DATA(insert ( 2206 2205 0 t ));
|
||||||
|
|
||||||
|
DATA(insert ( 23 702 0 t ));
|
||||||
|
DATA(insert ( 702 23 0 t ));
|
||||||
|
|
||||||
|
DATA(insert ( 23 703 0 t ));
|
||||||
|
DATA(insert ( 703 23 0 t ));
|
||||||
|
|
||||||
|
DATA(insert ( 650 869 0 t ));
|
||||||
|
DATA(insert ( 869 650 0 t ));
|
||||||
|
|
||||||
|
DATA(insert ( 1560 1562 0 t ));
|
||||||
|
DATA(insert ( 1562 1560 0 t ));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* regular casts through a function
|
||||||
|
*
|
||||||
|
* This list can be obtained from the following query as long as the
|
||||||
|
* naming convention of the cast functions remains the same:
|
||||||
|
*
|
||||||
|
* select p.proargtypes[0] as source, p.prorettype as target, p.oid as func, p.proimplicit as implicit from pg_proc p, pg_type t where p.pronargs=1 and p.proname = t.typname and p.prorettype = t.oid order by 1, 2;
|
||||||
|
*/
|
||||||
|
DATA(insert ( 18 25 946 t ));
|
||||||
|
DATA(insert ( 18 1042 860 t ));
|
||||||
|
DATA(insert ( 19 25 406 t ));
|
||||||
|
DATA(insert ( 19 1042 408 t ));
|
||||||
|
DATA(insert ( 19 1043 1401 t ));
|
||||||
|
DATA(insert ( 20 21 714 t ));
|
||||||
|
DATA(insert ( 20 23 480 t ));
|
||||||
|
DATA(insert ( 20 25 1288 t ));
|
||||||
|
DATA(insert ( 20 701 482 t ));
|
||||||
|
DATA(insert ( 20 1043 1623 f ));
|
||||||
|
DATA(insert ( 20 1700 1781 t ));
|
||||||
|
DATA(insert ( 21 20 754 t ));
|
||||||
|
DATA(insert ( 21 23 313 t ));
|
||||||
|
DATA(insert ( 21 25 113 t ));
|
||||||
|
DATA(insert ( 21 700 236 t ));
|
||||||
|
DATA(insert ( 21 701 235 t ));
|
||||||
|
DATA(insert ( 21 1700 1782 t ));
|
||||||
|
DATA(insert ( 23 20 481 t ));
|
||||||
|
DATA(insert ( 23 21 314 t ));
|
||||||
|
DATA(insert ( 23 25 112 t ));
|
||||||
|
DATA(insert ( 23 700 318 t ));
|
||||||
|
DATA(insert ( 23 701 316 t ));
|
||||||
|
/*xDATA(insert ( 23 703 1200 f ));*/
|
||||||
|
DATA(insert ( 23 1043 1619 f ));
|
||||||
|
DATA(insert ( 23 1700 1740 t ));
|
||||||
|
DATA(insert ( 25 18 944 t ));
|
||||||
|
DATA(insert ( 25 19 407 t ));
|
||||||
|
DATA(insert ( 25 20 1289 f ));
|
||||||
|
DATA(insert ( 25 21 818 f ));
|
||||||
|
DATA(insert ( 25 23 819 f ));
|
||||||
|
DATA(insert ( 25 26 817 f ));
|
||||||
|
DATA(insert ( 25 650 1714 f ));
|
||||||
|
DATA(insert ( 25 700 839 f ));
|
||||||
|
DATA(insert ( 25 701 838 f ));
|
||||||
|
DATA(insert ( 25 829 767 f ));
|
||||||
|
DATA(insert ( 25 869 1713 f ));
|
||||||
|
DATA(insert ( 25 1082 748 f ));
|
||||||
|
DATA(insert ( 25 1083 837 f ));
|
||||||
|
DATA(insert ( 25 1114 2022 f ));
|
||||||
|
DATA(insert ( 25 1184 1191 f ));
|
||||||
|
DATA(insert ( 25 1186 1263 f ));
|
||||||
|
DATA(insert ( 25 1266 938 f ));
|
||||||
|
DATA(insert ( 26 25 114 f ));
|
||||||
|
DATA(insert ( 601 600 1532 f ));
|
||||||
|
DATA(insert ( 602 600 1533 f ));
|
||||||
|
DATA(insert ( 602 604 1449 f ));
|
||||||
|
DATA(insert ( 603 600 1534 f ));
|
||||||
|
DATA(insert ( 603 601 1541 f ));
|
||||||
|
DATA(insert ( 603 604 1448 f ));
|
||||||
|
DATA(insert ( 603 718 1479 f ));
|
||||||
|
DATA(insert ( 604 600 1540 f ));
|
||||||
|
DATA(insert ( 604 602 1447 f ));
|
||||||
|
DATA(insert ( 604 603 1446 f ));
|
||||||
|
DATA(insert ( 604 718 1474 f ));
|
||||||
|
DATA(insert ( 700 21 238 f ));
|
||||||
|
DATA(insert ( 700 23 319 f ));
|
||||||
|
DATA(insert ( 700 25 841 t ));
|
||||||
|
DATA(insert ( 700 701 311 t ));
|
||||||
|
DATA(insert ( 700 1700 1742 t ));
|
||||||
|
DATA(insert ( 701 20 483 f ));
|
||||||
|
DATA(insert ( 701 21 237 f ));
|
||||||
|
DATA(insert ( 701 23 317 f ));
|
||||||
|
DATA(insert ( 701 25 840 t ));
|
||||||
|
DATA(insert ( 701 700 312 t ));
|
||||||
|
DATA(insert ( 701 1700 1743 t ));
|
||||||
|
DATA(insert ( 702 1082 1179 f ));
|
||||||
|
DATA(insert ( 702 1083 1364 f ));
|
||||||
|
DATA(insert ( 702 1114 2023 t ));
|
||||||
|
DATA(insert ( 702 1184 1173 t ));
|
||||||
|
DATA(insert ( 703 1186 1177 t ));
|
||||||
|
DATA(insert ( 718 600 1416 f ));
|
||||||
|
DATA(insert ( 718 603 1480 f ));
|
||||||
|
DATA(insert ( 718 604 1544 f ));
|
||||||
|
DATA(insert ( 829 25 752 f ));
|
||||||
|
DATA(insert ( 869 25 730 f ));
|
||||||
|
DATA(insert ( 1042 19 409 t ));
|
||||||
|
DATA(insert ( 1043 19 1400 t ));
|
||||||
|
DATA(insert ( 1082 25 749 t ));
|
||||||
|
DATA(insert ( 1082 1114 2024 t ));
|
||||||
|
DATA(insert ( 1082 1184 1174 t ));
|
||||||
|
DATA(insert ( 1083 25 948 t ));
|
||||||
|
DATA(insert ( 1083 1186 1370 t ));
|
||||||
|
DATA(insert ( 1083 1266 2047 t ));
|
||||||
|
DATA(insert ( 1114 25 2034 t ));
|
||||||
|
DATA(insert ( 1114 702 2030 f ));
|
||||||
|
DATA(insert ( 1114 1082 2029 f ));
|
||||||
|
DATA(insert ( 1114 1083 1316 f ));
|
||||||
|
DATA(insert ( 1114 1184 2028 t ));
|
||||||
|
DATA(insert ( 1184 25 1192 t ));
|
||||||
|
DATA(insert ( 1184 702 1180 f ));
|
||||||
|
DATA(insert ( 1184 1082 1178 f ));
|
||||||
|
DATA(insert ( 1184 1083 2019 f ));
|
||||||
|
DATA(insert ( 1184 1114 2027 t ));
|
||||||
|
DATA(insert ( 1184 1266 1388 f ));
|
||||||
|
DATA(insert ( 1186 25 1193 t ));
|
||||||
|
DATA(insert ( 1186 703 1194 f ));
|
||||||
|
DATA(insert ( 1186 1083 1419 f ));
|
||||||
|
DATA(insert ( 1266 25 939 t ));
|
||||||
|
DATA(insert ( 1266 1083 2046 t ));
|
||||||
|
DATA(insert ( 1700 20 1779 f ));
|
||||||
|
DATA(insert ( 1700 21 1783 f ));
|
||||||
|
DATA(insert ( 1700 23 1744 f ));
|
||||||
|
DATA(insert ( 1700 700 1745 f ));
|
||||||
|
DATA(insert ( 1700 701 1746 f ));
|
||||||
|
|
||||||
|
#endif /* PG_CAST_H */
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_proc.h,v 1.243 2002/06/20 20:29:44 momjian Exp $
|
* $Id: pg_proc.h,v 1.244 2002/07/18 23:11:30 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -45,7 +45,7 @@ CATALOG(pg_proc) BOOTSTRAP
|
|||||||
Oid prolang; /* OID of pg_language entry */
|
Oid prolang; /* OID of pg_language entry */
|
||||||
bool proisagg; /* is it an aggregate? */
|
bool proisagg; /* is it an aggregate? */
|
||||||
bool prosecdef; /* security definer */
|
bool prosecdef; /* security definer */
|
||||||
bool proimplicit; /* can be invoked as implicit coercion? */
|
bool proimplicit; /* unused */
|
||||||
bool proisstrict; /* strict with respect to NULLs? */
|
bool proisstrict; /* strict with respect to NULLs? */
|
||||||
bool proretset; /* returns a set? */
|
bool proretset; /* returns a set? */
|
||||||
char provolatile; /* see PROVOLATILE_ categories below */
|
char provolatile; /* see PROVOLATILE_ categories below */
|
||||||
@ -3007,7 +3007,6 @@ extern Oid ProcedureCreate(const char *procedureName,
|
|||||||
const char *probin,
|
const char *probin,
|
||||||
bool isAgg,
|
bool isAgg,
|
||||||
bool security_definer,
|
bool security_definer,
|
||||||
bool isImplicit,
|
|
||||||
bool isStrict,
|
bool isStrict,
|
||||||
char volatility,
|
char volatility,
|
||||||
int32 byte_pct,
|
int32 byte_pct,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: defrem.h,v 1.41 2002/07/12 18:43:19 tgl Exp $
|
* $Id: defrem.h,v 1.42 2002/07/18 23:11:32 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -42,6 +42,9 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all);
|
|||||||
extern void CreateFunction(CreateFunctionStmt *stmt);
|
extern void CreateFunction(CreateFunctionStmt *stmt);
|
||||||
extern void RemoveFunction(RemoveFuncStmt *stmt);
|
extern void RemoveFunction(RemoveFuncStmt *stmt);
|
||||||
extern void RemoveFunctionById(Oid funcOid);
|
extern void RemoveFunctionById(Oid funcOid);
|
||||||
|
extern void CreateCast(CreateCastStmt *stmt);
|
||||||
|
extern void DropCast(DropCastStmt *stmt);
|
||||||
|
extern void DropCastById(Oid castOid);
|
||||||
|
|
||||||
extern void DefineOperator(List *names, List *parameters);
|
extern void DefineOperator(List *names, List *parameters);
|
||||||
extern void RemoveOperator(RemoveOperStmt *stmt);
|
extern void RemoveOperator(RemoveOperStmt *stmt);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: nodes.h,v 1.112 2002/07/18 17:14:20 momjian Exp $
|
* $Id: nodes.h,v 1.113 2002/07/18 23:11:32 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -199,6 +199,8 @@ typedef enum NodeTag
|
|||||||
T_AlterDatabaseSetStmt,
|
T_AlterDatabaseSetStmt,
|
||||||
T_AlterUserSetStmt,
|
T_AlterUserSetStmt,
|
||||||
T_CreateConversionStmt,
|
T_CreateConversionStmt,
|
||||||
|
T_CreateCastStmt,
|
||||||
|
T_DropCastStmt,
|
||||||
|
|
||||||
T_A_Expr = 700,
|
T_A_Expr = 700,
|
||||||
T_ColumnRef,
|
T_ColumnRef,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: parsenodes.h,v 1.192 2002/07/18 17:14:20 momjian Exp $
|
* $Id: parsenodes.h,v 1.193 2002/07/18 23:11:32 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1555,4 +1555,30 @@ typedef struct CreateConversionStmt
|
|||||||
bool def; /* is this a default conversion? */
|
bool def; /* is this a default conversion? */
|
||||||
} CreateConversionStmt;
|
} CreateConversionStmt;
|
||||||
|
|
||||||
|
/* ----------------------
|
||||||
|
* CREATE CAST Statement
|
||||||
|
* ----------------------
|
||||||
|
*/
|
||||||
|
typedef struct CreateCastStmt
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
TypeName *sourcetype;
|
||||||
|
TypeName *targettype;
|
||||||
|
FuncWithArgs *func;
|
||||||
|
bool implicit;
|
||||||
|
} CreateCastStmt;
|
||||||
|
|
||||||
|
/* ----------------------
|
||||||
|
* DROP CAST Statement
|
||||||
|
* ----------------------
|
||||||
|
*/
|
||||||
|
typedef struct DropCastStmt
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
TypeName *sourcetype;
|
||||||
|
TypeName *targettype;
|
||||||
|
DropBehavior behavior;
|
||||||
|
} DropCastStmt;
|
||||||
|
|
||||||
|
|
||||||
#endif /* PARSENODES_H */
|
#endif /* PARSENODES_H */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: syscache.h,v 1.49 2002/07/11 07:39:28 ishii Exp $
|
* $Id: syscache.h,v 1.50 2002/07/18 23:11:32 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -36,29 +36,30 @@
|
|||||||
#define AMPROCNUM 5
|
#define AMPROCNUM 5
|
||||||
#define ATTNAME 6
|
#define ATTNAME 6
|
||||||
#define ATTNUM 7
|
#define ATTNUM 7
|
||||||
#define CLAAMNAMENSP 8
|
#define CASTSOURCETARGET 8
|
||||||
#define CLAOID 9
|
#define CLAAMNAMENSP 9
|
||||||
#define CONNAMESP 10
|
#define CLAOID 10
|
||||||
#define GRONAME 11
|
#define CONNAMESP 11
|
||||||
#define GROSYSID 12
|
#define GRONAME 12
|
||||||
#define INDEXRELID 13
|
#define GROSYSID 13
|
||||||
#define INHRELID 14
|
#define INDEXRELID 14
|
||||||
#define LANGNAME 15
|
#define INHRELID 15
|
||||||
#define LANGOID 16
|
#define LANGNAME 16
|
||||||
#define NAMESPACENAME 17
|
#define LANGOID 17
|
||||||
#define NAMESPACEOID 18
|
#define NAMESPACENAME 18
|
||||||
#define OPERNAMENSP 19
|
#define NAMESPACEOID 19
|
||||||
#define OPEROID 20
|
#define OPERNAMENSP 20
|
||||||
#define PROCNAMENSP 21
|
#define OPEROID 21
|
||||||
#define PROCOID 22
|
#define PROCNAMENSP 22
|
||||||
#define RELNAMENSP 23
|
#define PROCOID 23
|
||||||
#define RELOID 24
|
#define RELNAMENSP 24
|
||||||
#define RULERELNAME 25
|
#define RELOID 25
|
||||||
#define SHADOWNAME 26
|
#define RULERELNAME 26
|
||||||
#define SHADOWSYSID 27
|
#define SHADOWNAME 27
|
||||||
#define STATRELATT 28
|
#define SHADOWSYSID 28
|
||||||
#define TYPENAMENSP 29
|
#define STATRELATT 29
|
||||||
#define TYPEOID 30
|
#define TYPENAMENSP 30
|
||||||
|
#define TYPEOID 31
|
||||||
|
|
||||||
extern void InitCatalogCache(void);
|
extern void InitCatalogCache(void);
|
||||||
extern void InitCatalogCachePhase2(void);
|
extern void InitCatalogCachePhase2(void);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
--
|
--
|
||||||
-- OPR_SANITY
|
-- OPR_SANITY
|
||||||
-- Sanity checks for common errors in making operator/procedure system tables:
|
-- Sanity checks for common errors in making operator/procedure system tables:
|
||||||
-- pg_operator, pg_proc, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass.
|
-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass.
|
||||||
--
|
--
|
||||||
-- None of the SELECTs here should ever find any matching entries,
|
-- None of the SELECTs here should ever find any matching entries,
|
||||||
-- so the expected output is easy to maintain ;-).
|
-- so the expected output is easy to maintain ;-).
|
||||||
@ -180,20 +180,49 @@ WHERE p1.oid != p2.oid AND
|
|||||||
-------------+-------------
|
-------------+-------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- If a proc is marked as an implicit cast, then it should be something that
|
-- **************** pg_cast ****************
|
||||||
-- the system might actually use as a cast function: name same as the name
|
-- Look for casts from and to the same type. This is not harmful, but
|
||||||
-- of its output type, and either one arg that's a different type, or two
|
-- useless.
|
||||||
-- args where the first is the same as the output type and the second is int4.
|
SELECT *
|
||||||
SELECT p1.oid, p1.proname
|
FROM pg_cast c
|
||||||
FROM pg_proc as p1
|
WHERE c.castsource = c.casttarget;
|
||||||
WHERE p1.proimplicit AND
|
castsource | casttarget | castfunc | castimplicit
|
||||||
(NOT EXISTS (SELECT 1 FROM pg_type t WHERE t.oid = p1.prorettype AND
|
------------+------------+----------+--------------
|
||||||
t.typname = p1.proname) OR
|
(0 rows)
|
||||||
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
|
|
||||||
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
|
-- Look for cast functions with incorrect number or type of argument
|
||||||
p1.proargtypes[1] = 'int4'::regtype)));
|
-- or return value.
|
||||||
oid | proname
|
SELECT c.*
|
||||||
-----+---------
|
FROM pg_cast c, pg_proc p
|
||||||
|
WHERE c.castfunc = p.oid AND
|
||||||
|
(p.pronargs <> 1 OR
|
||||||
|
p.proargtypes[0] <> c.castsource OR
|
||||||
|
p.prorettype <> c.casttarget);
|
||||||
|
castsource | casttarget | castfunc | castimplicit
|
||||||
|
------------+------------+----------+--------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- Look for binary compatible casts that are not implicit. This is
|
||||||
|
-- legal, but probably not intended.
|
||||||
|
SELECT *
|
||||||
|
FROM pg_cast c
|
||||||
|
WHERE c.castfunc = 0 AND NOT c.castimplicit;
|
||||||
|
castsource | casttarget | castfunc | castimplicit
|
||||||
|
------------+------------+----------+--------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- Look for binary compatible casts that do not have the reverse
|
||||||
|
-- direction registered as well, or where the reverse direction is not
|
||||||
|
-- also binary compatible. This is legal, but probably not intended.
|
||||||
|
SELECT *
|
||||||
|
FROM pg_cast c
|
||||||
|
WHERE c.castfunc = 0 AND
|
||||||
|
NOT EXISTS (SELECT * FROM pg_cast k
|
||||||
|
WHERE k.castfunc = 0 AND
|
||||||
|
k.castsource = c.casttarget AND
|
||||||
|
k.casttarget = c.castsource);
|
||||||
|
castsource | casttarget | castfunc | castimplicit
|
||||||
|
------------+------------+----------+--------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- **************** pg_operator ****************
|
-- **************** pg_operator ****************
|
||||||
|
@ -37,6 +37,7 @@ SELECT relname, relhasindex
|
|||||||
pg_amproc | t
|
pg_amproc | t
|
||||||
pg_attrdef | t
|
pg_attrdef | t
|
||||||
pg_attribute | t
|
pg_attribute | t
|
||||||
|
pg_cast | t
|
||||||
pg_class | t
|
pg_class | t
|
||||||
pg_constraint | t
|
pg_constraint | t
|
||||||
pg_conversion | t
|
pg_conversion | t
|
||||||
@ -62,5 +63,5 @@ SELECT relname, relhasindex
|
|||||||
shighway | t
|
shighway | t
|
||||||
tenk1 | t
|
tenk1 | t
|
||||||
tenk2 | t
|
tenk2 | t
|
||||||
(52 rows)
|
(53 rows)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
--
|
--
|
||||||
-- OPR_SANITY
|
-- OPR_SANITY
|
||||||
-- Sanity checks for common errors in making operator/procedure system tables:
|
-- Sanity checks for common errors in making operator/procedure system tables:
|
||||||
-- pg_operator, pg_proc, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass.
|
-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass.
|
||||||
--
|
--
|
||||||
-- None of the SELECTs here should ever find any matching entries,
|
-- None of the SELECTs here should ever find any matching entries,
|
||||||
-- so the expected output is easy to maintain ;-).
|
-- so the expected output is easy to maintain ;-).
|
||||||
@ -141,19 +141,43 @@ WHERE p1.oid != p2.oid AND
|
|||||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||||
(p1.proargtypes[7] < p2.proargtypes[7]);
|
(p1.proargtypes[7] < p2.proargtypes[7]);
|
||||||
|
|
||||||
-- If a proc is marked as an implicit cast, then it should be something that
|
-- **************** pg_cast ****************
|
||||||
-- the system might actually use as a cast function: name same as the name
|
|
||||||
-- of its output type, and either one arg that's a different type, or two
|
|
||||||
-- args where the first is the same as the output type and the second is int4.
|
|
||||||
|
|
||||||
SELECT p1.oid, p1.proname
|
-- Look for casts from and to the same type. This is not harmful, but
|
||||||
FROM pg_proc as p1
|
-- useless.
|
||||||
WHERE p1.proimplicit AND
|
|
||||||
(NOT EXISTS (SELECT 1 FROM pg_type t WHERE t.oid = p1.prorettype AND
|
SELECT *
|
||||||
t.typname = p1.proname) OR
|
FROM pg_cast c
|
||||||
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
|
WHERE c.castsource = c.casttarget;
|
||||||
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
|
|
||||||
p1.proargtypes[1] = 'int4'::regtype)));
|
-- Look for cast functions with incorrect number or type of argument
|
||||||
|
-- or return value.
|
||||||
|
|
||||||
|
SELECT c.*
|
||||||
|
FROM pg_cast c, pg_proc p
|
||||||
|
WHERE c.castfunc = p.oid AND
|
||||||
|
(p.pronargs <> 1 OR
|
||||||
|
p.proargtypes[0] <> c.castsource OR
|
||||||
|
p.prorettype <> c.casttarget);
|
||||||
|
|
||||||
|
-- Look for binary compatible casts that are not implicit. This is
|
||||||
|
-- legal, but probably not intended.
|
||||||
|
|
||||||
|
SELECT *
|
||||||
|
FROM pg_cast c
|
||||||
|
WHERE c.castfunc = 0 AND NOT c.castimplicit;
|
||||||
|
|
||||||
|
-- Look for binary compatible casts that do not have the reverse
|
||||||
|
-- direction registered as well, or where the reverse direction is not
|
||||||
|
-- also binary compatible. This is legal, but probably not intended.
|
||||||
|
|
||||||
|
SELECT *
|
||||||
|
FROM pg_cast c
|
||||||
|
WHERE c.castfunc = 0 AND
|
||||||
|
NOT EXISTS (SELECT * FROM pg_cast k
|
||||||
|
WHERE k.castfunc = 0 AND
|
||||||
|
k.castsource = c.casttarget AND
|
||||||
|
k.casttarget = c.castsource);
|
||||||
|
|
||||||
-- **************** pg_operator ****************
|
-- **************** pg_operator ****************
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user