Add support for user-defined I/O conversion casts.
This commit is contained in:
parent
34e37d58ed
commit
092bc49653
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.179 2008/10/17 22:10:29 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.180 2008/10/31 08:39:19 heikki Exp $ -->
|
||||||
<!--
|
<!--
|
||||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
-->
|
-->
|
||||||
@ -1415,9 +1415,10 @@
|
|||||||
cannot be deduced from some generic rule. For example, casting between a
|
cannot be deduced from some generic rule. For example, casting between a
|
||||||
domain and its base type is not explicitly represented in
|
domain and its base type is not explicitly represented in
|
||||||
<structname>pg_cast</structname>. Another important exception is that
|
<structname>pg_cast</structname>. Another important exception is that
|
||||||
<quote>I/O conversion casts</>, those performed using a data type's own
|
<quote>automatic I/O conversion casts</>, those performed using a data
|
||||||
I/O functions to convert to or from <type>text</> or other string types,
|
type's own I/O functions to convert to or from <type>text</> or other
|
||||||
are not explicitly represented in <structname>pg_cast</structname>.
|
string types, are not explicitly represented in
|
||||||
|
<structname>pg_cast</structname>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
@ -1454,8 +1455,7 @@
|
|||||||
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
|
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
|
||||||
<entry>
|
<entry>
|
||||||
The OID of the function to use to perform this cast. Zero is
|
The OID of the function to use to perform this cast. Zero is
|
||||||
stored if the data types are binary coercible (that is, no
|
stored if the cast method doesn't require a function.
|
||||||
run-time operation is needed to perform the cast)
|
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -1473,6 +1473,17 @@
|
|||||||
other cases
|
other cases
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>castmethod</structfield></entry>
|
||||||
|
<entry><type>char</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>
|
||||||
|
Indicates how the cast is performed.
|
||||||
|
<literal>f</> means that the function specified in the <structfield>castfunc</> field is used.
|
||||||
|
<literal>i</> means that the input/output functions are used.
|
||||||
|
<literal>b</> means that the types are binary-coercible, thus no conversion is required
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.29 2008/07/30 21:23:17 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.30 2008/10/31 08:39:20 heikki Exp $ -->
|
||||||
|
|
||||||
<refentry id="SQL-CREATECAST">
|
<refentry id="SQL-CREATECAST">
|
||||||
<refmeta>
|
<refmeta>
|
||||||
@ -24,6 +24,10 @@ CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</r
|
|||||||
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
|
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
|
||||||
WITHOUT FUNCTION
|
WITHOUT FUNCTION
|
||||||
[ AS ASSIGNMENT | AS IMPLICIT ]
|
[ AS ASSIGNMENT | AS IMPLICIT ]
|
||||||
|
|
||||||
|
CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
|
||||||
|
WITH INOUT
|
||||||
|
[ AS ASSIGNMENT | AS IMPLICIT ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -58,6 +62,13 @@ SELECT CAST(42 AS float8);
|
|||||||
binary compatible.)
|
binary compatible.)
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You can define a cast as an <firstterm>I/O conversion cast</> using
|
||||||
|
the <literal>WITH INOUT</literal> syntax. An I/O conversion cast is
|
||||||
|
performed by invoking the output function of the source data type, and
|
||||||
|
passing the result to the input function of the target data type.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
By default, a cast can be invoked only by an explicit cast request,
|
By default, a cast can be invoked only by an explicit cast request,
|
||||||
that is an explicit <literal>CAST(<replaceable>x</> AS
|
that is an explicit <literal>CAST(<replaceable>x</> AS
|
||||||
@ -199,6 +210,18 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>WITH INOUT</literal></term>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Indicates that the cast is an I/O conversion cast, performed by
|
||||||
|
invoking the output function of the source data type, and passing the
|
||||||
|
result to the input function of the target data type.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>AS ASSIGNMENT</literal></term>
|
<term><literal>AS ASSIGNMENT</literal></term>
|
||||||
|
|
||||||
@ -284,15 +307,12 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
It is normally not necessary to create casts between user-defined types
|
It is normally not necessary to create casts between user-defined types
|
||||||
and the standard string types (<type>text</>, <type>varchar</>, and
|
and the standard string types (<type>text</>, <type>varchar</>, and
|
||||||
<type>char(<replaceable>n</>)</type>, as well as user-defined types that
|
<type>char(<replaceable>n</>)</type>, as well as user-defined types that
|
||||||
are defined to be in the string category). <productname>PostgreSQL</> will
|
are defined to be in the string category). <productname>PostgreSQL</>
|
||||||
automatically handle a cast to a string type by invoking the other
|
provides automatic I/O conversion casts for that. The automatic casts to
|
||||||
type's output function, or conversely handle a cast from a string type
|
string types are treated as assignment casts, while the automatic casts
|
||||||
by invoking the other type's input function. These
|
from string types are
|
||||||
automatically-provided casts are known as <firstterm>I/O conversion
|
|
||||||
casts</>. I/O conversion casts to string types are treated as
|
|
||||||
assignment casts, while I/O conversion casts from string types are
|
|
||||||
explicit-only. You can override this behavior by declaring your own
|
explicit-only. You can override this behavior by declaring your own
|
||||||
cast to replace an I/O conversion cast, but usually the only reason to
|
cast to replace an automatic cast, but usually the only reason to
|
||||||
do so is if you want the conversion to be more easily invokable than the
|
do so is if you want the conversion to be more easily invokable than the
|
||||||
standard assignment-only or explicit-only setting. Another possible
|
standard assignment-only or explicit-only setting. Another possible
|
||||||
reason is that you want the conversion to behave differently from the
|
reason is that you want the conversion to behave differently from the
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.99 2008/10/21 10:38:51 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.100 2008/10/31 08:39:20 heikki Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* These routines take the parse tree and pick out the
|
* These routines take the parse tree and pick out the
|
||||||
@ -1383,6 +1383,7 @@ CreateCast(CreateCastStmt *stmt)
|
|||||||
Oid funcid;
|
Oid funcid;
|
||||||
int nargs;
|
int nargs;
|
||||||
char castcontext;
|
char castcontext;
|
||||||
|
char castmethod;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum values[Natts_pg_cast];
|
Datum values[Natts_pg_cast];
|
||||||
@ -1415,7 +1416,15 @@ CreateCast(CreateCastStmt *stmt)
|
|||||||
format_type_be(sourcetypeid),
|
format_type_be(sourcetypeid),
|
||||||
format_type_be(targettypeid))));
|
format_type_be(targettypeid))));
|
||||||
|
|
||||||
|
/* Detemine the cast method */
|
||||||
if (stmt->func != NULL)
|
if (stmt->func != NULL)
|
||||||
|
castmethod = COERCION_METHOD_FUNCTION;
|
||||||
|
else if(stmt->inout)
|
||||||
|
castmethod = COERCION_METHOD_INOUT;
|
||||||
|
else
|
||||||
|
castmethod = COERCION_METHOD_BINARY;
|
||||||
|
|
||||||
|
if (castmethod == COERCION_METHOD_FUNCTION)
|
||||||
{
|
{
|
||||||
Form_pg_proc procstruct;
|
Form_pg_proc procstruct;
|
||||||
|
|
||||||
@ -1475,6 +1484,12 @@ CreateCast(CreateCastStmt *stmt)
|
|||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
funcid = InvalidOid;
|
||||||
|
nargs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (castmethod == COERCION_METHOD_BINARY)
|
||||||
{
|
{
|
||||||
int16 typ1len;
|
int16 typ1len;
|
||||||
int16 typ2len;
|
int16 typ2len;
|
||||||
@ -1483,10 +1498,6 @@ CreateCast(CreateCastStmt *stmt)
|
|||||||
char typ1align;
|
char typ1align;
|
||||||
char typ2align;
|
char typ2align;
|
||||||
|
|
||||||
/* indicates binary coercibility */
|
|
||||||
funcid = InvalidOid;
|
|
||||||
nargs = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be superuser to create binary-compatible casts, since
|
* Must be superuser to create binary-compatible casts, since
|
||||||
* erroneous casts can easily crash the backend.
|
* erroneous casts can easily crash the backend.
|
||||||
@ -1562,6 +1573,7 @@ CreateCast(CreateCastStmt *stmt)
|
|||||||
values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
|
values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
|
||||||
values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
|
values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
|
||||||
values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
|
values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
|
||||||
|
values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
|
||||||
|
|
||||||
MemSet(nulls, ' ', Natts_pg_cast);
|
MemSet(nulls, ' ', Natts_pg_cast);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.409 2008/10/21 20:42:52 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.410 2008/10/31 08:39:20 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3042,6 +3042,7 @@ _copyCreateCastStmt(CreateCastStmt *from)
|
|||||||
COPY_NODE_FIELD(targettype);
|
COPY_NODE_FIELD(targettype);
|
||||||
COPY_NODE_FIELD(func);
|
COPY_NODE_FIELD(func);
|
||||||
COPY_SCALAR_FIELD(context);
|
COPY_SCALAR_FIELD(context);
|
||||||
|
COPY_SCALAR_FIELD(inout);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.334 2008/10/21 20:42:52 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.335 2008/10/31 08:39:20 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1666,6 +1666,7 @@ _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
|
|||||||
COMPARE_NODE_FIELD(targettype);
|
COMPARE_NODE_FIELD(targettype);
|
||||||
COMPARE_NODE_FIELD(func);
|
COMPARE_NODE_FIELD(func);
|
||||||
COMPARE_SCALAR_FIELD(context);
|
COMPARE_SCALAR_FIELD(context);
|
||||||
|
COMPARE_SCALAR_FIELD(inout);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.632 2008/10/29 11:24:53 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.633 2008/10/31 08:39:20 heikki Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -4590,6 +4590,7 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
|
|||||||
n->targettype = $6;
|
n->targettype = $6;
|
||||||
n->func = $10;
|
n->func = $10;
|
||||||
n->context = (CoercionContext) $11;
|
n->context = (CoercionContext) $11;
|
||||||
|
n->inout = false;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| CREATE CAST '(' Typename AS Typename ')'
|
| CREATE CAST '(' Typename AS Typename ')'
|
||||||
@ -4600,6 +4601,18 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
|
|||||||
n->targettype = $6;
|
n->targettype = $6;
|
||||||
n->func = NULL;
|
n->func = NULL;
|
||||||
n->context = (CoercionContext) $10;
|
n->context = (CoercionContext) $10;
|
||||||
|
n->inout = false;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
|
| CREATE CAST '(' Typename AS Typename ')'
|
||||||
|
WITH INOUT cast_context
|
||||||
|
{
|
||||||
|
CreateCastStmt *n = makeNode(CreateCastStmt);
|
||||||
|
n->sourcetype = $4;
|
||||||
|
n->targettype = $6;
|
||||||
|
n->func = NULL;
|
||||||
|
n->context = (CoercionContext) $10;
|
||||||
|
n->inout = true;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.170 2008/10/25 17:19:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.171 2008/10/31 08:39:21 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1909,11 +1909,23 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
|
|||||||
/* Rely on ordering of enum for correct behavior here */
|
/* Rely on ordering of enum for correct behavior here */
|
||||||
if (ccontext >= castcontext)
|
if (ccontext >= castcontext)
|
||||||
{
|
{
|
||||||
*funcid = castForm->castfunc;
|
switch (castForm->castmethod)
|
||||||
if (OidIsValid(*funcid))
|
{
|
||||||
result = COERCION_PATH_FUNC;
|
case COERCION_METHOD_FUNCTION:
|
||||||
else
|
result = COERCION_PATH_FUNC;
|
||||||
result = COERCION_PATH_RELABELTYPE;
|
*funcid = castForm->castfunc;
|
||||||
|
break;
|
||||||
|
case COERCION_METHOD_INOUT:
|
||||||
|
result = COERCION_PATH_COERCEVIAIO;
|
||||||
|
break;
|
||||||
|
case COERCION_METHOD_BINARY:
|
||||||
|
result = COERCION_PATH_RELABELTYPE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unrecognized castmethod: %d",
|
||||||
|
(int) castForm->castmethod);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* by PostgreSQL
|
* by PostgreSQL
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.502 2008/09/24 19:33:15 heikki Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.503 2008/10/31 08:39:21 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -36,6 +36,7 @@ int optreset;
|
|||||||
|
|
||||||
#include "access/attnum.h"
|
#include "access/attnum.h"
|
||||||
#include "access/sysattr.h"
|
#include "access/sysattr.h"
|
||||||
|
#include "catalog/pg_cast.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_trigger.h"
|
#include "catalog/pg_trigger.h"
|
||||||
@ -4410,21 +4411,31 @@ getCasts(int *numCasts)
|
|||||||
int i_casttarget;
|
int i_casttarget;
|
||||||
int i_castfunc;
|
int i_castfunc;
|
||||||
int i_castcontext;
|
int i_castcontext;
|
||||||
|
int i_castmethod;
|
||||||
|
|
||||||
/* Make sure we are in proper schema */
|
/* Make sure we are in proper schema */
|
||||||
selectSourceSchema("pg_catalog");
|
selectSourceSchema("pg_catalog");
|
||||||
|
|
||||||
if (g_fout->remoteVersion >= 70300)
|
if (g_fout->remoteVersion >= 80400)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(query, "SELECT tableoid, oid, "
|
appendPQExpBuffer(query, "SELECT tableoid, oid, "
|
||||||
"castsource, casttarget, castfunc, castcontext "
|
"castsource, casttarget, castfunc, castcontext, "
|
||||||
|
"castmethod "
|
||||||
|
"FROM pg_cast ORDER BY 3,4");
|
||||||
|
}
|
||||||
|
else if (g_fout->remoteVersion >= 70300)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(query, "SELECT tableoid, oid, "
|
||||||
|
"castsource, casttarget, castfunc, castcontext, "
|
||||||
|
"CASE WHEN castfunc = 0 THEN 'b' ELSE 'f' END AS castmethod "
|
||||||
"FROM pg_cast ORDER BY 3,4");
|
"FROM pg_cast ORDER BY 3,4");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(query, "SELECT 0 as tableoid, p.oid, "
|
appendPQExpBuffer(query, "SELECT 0 as tableoid, p.oid, "
|
||||||
"t1.oid as castsource, t2.oid as casttarget, "
|
"t1.oid as castsource, t2.oid as casttarget, "
|
||||||
"p.oid as castfunc, 'e' as castcontext "
|
"p.oid as castfunc, 'e' as castcontext, "
|
||||||
|
"'f' as castmethod "
|
||||||
"FROM pg_type t1, pg_type t2, pg_proc p "
|
"FROM pg_type t1, pg_type t2, pg_proc p "
|
||||||
"WHERE p.pronargs = 1 AND "
|
"WHERE p.pronargs = 1 AND "
|
||||||
"p.proargtypes[0] = t1.oid AND "
|
"p.proargtypes[0] = t1.oid AND "
|
||||||
@ -4447,6 +4458,7 @@ getCasts(int *numCasts)
|
|||||||
i_casttarget = PQfnumber(res, "casttarget");
|
i_casttarget = PQfnumber(res, "casttarget");
|
||||||
i_castfunc = PQfnumber(res, "castfunc");
|
i_castfunc = PQfnumber(res, "castfunc");
|
||||||
i_castcontext = PQfnumber(res, "castcontext");
|
i_castcontext = PQfnumber(res, "castcontext");
|
||||||
|
i_castmethod = PQfnumber(res, "castmethod");
|
||||||
|
|
||||||
for (i = 0; i < ntups; i++)
|
for (i = 0; i < ntups; i++)
|
||||||
{
|
{
|
||||||
@ -4462,6 +4474,7 @@ getCasts(int *numCasts)
|
|||||||
castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
|
castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
|
||||||
castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
|
castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
|
||||||
castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
|
castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
|
||||||
|
castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to name cast as concatenation of typnames. This is only used
|
* Try to name cast as concatenation of typnames. This is only used
|
||||||
@ -7188,18 +7201,26 @@ dumpCast(Archive *fout, CastInfo *cast)
|
|||||||
getFormattedTypeName(cast->castsource, zeroAsNone),
|
getFormattedTypeName(cast->castsource, zeroAsNone),
|
||||||
getFormattedTypeName(cast->casttarget, zeroAsNone));
|
getFormattedTypeName(cast->casttarget, zeroAsNone));
|
||||||
|
|
||||||
if (!OidIsValid(cast->castfunc))
|
switch(cast->castmethod)
|
||||||
appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/*
|
case COERCION_METHOD_BINARY:
|
||||||
* Always qualify the function name, in case it is not in pg_catalog
|
appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
|
||||||
* schema (format_function_signature won't qualify it).
|
break;
|
||||||
*/
|
case COERCION_METHOD_INOUT:
|
||||||
appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
|
appendPQExpBuffer(defqry, "WITH INOUT");
|
||||||
fmtId(funcInfo->dobj.namespace->dobj.name));
|
break;
|
||||||
appendPQExpBuffer(defqry, "%s",
|
case COERCION_METHOD_FUNCTION:
|
||||||
format_function_signature(funcInfo, true));
|
/*
|
||||||
|
* Always qualify the function name, in case it is not in
|
||||||
|
* pg_catalog schema (format_function_signature won't qualify it).
|
||||||
|
*/
|
||||||
|
appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
|
||||||
|
fmtId(funcInfo->dobj.namespace->dobj.name));
|
||||||
|
appendPQExpBuffer(defqry, "%s",
|
||||||
|
format_function_signature(funcInfo, true));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cast->castcontext == 'a')
|
if (cast->castcontext == 'a')
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.141 2008/09/08 15:26:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.142 2008/10/31 08:39:21 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -376,6 +376,7 @@ typedef struct _castInfo
|
|||||||
Oid casttarget;
|
Oid casttarget;
|
||||||
Oid castfunc;
|
Oid castfunc;
|
||||||
char castcontext;
|
char castcontext;
|
||||||
|
char castmethod;
|
||||||
} CastInfo;
|
} CastInfo;
|
||||||
|
|
||||||
/* InhInfo isn't a DumpableObject, just temporary state */
|
/* InhInfo isn't a DumpableObject, just temporary state */
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.499 2008/10/17 22:10:30 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.500 2008/10/31 08:39:22 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200810171
|
#define CATALOG_VERSION_NO 200810311
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2002-2008, PostgreSQL Global Development Group
|
* Copyright (c) 2002-2008, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.39 2008/03/27 03:57:34 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.40 2008/10/31 08:39:22 heikki Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -36,6 +36,7 @@ CATALOG(pg_cast,2605)
|
|||||||
Oid casttarget; /* destination datatype for cast */
|
Oid casttarget; /* destination datatype for cast */
|
||||||
Oid castfunc; /* cast function; 0 = binary coercible */
|
Oid castfunc; /* cast function; 0 = binary coercible */
|
||||||
char castcontext; /* contexts in which cast can be used */
|
char castcontext; /* contexts in which cast can be used */
|
||||||
|
char castmethod; /* cast method */
|
||||||
} FormData_pg_cast;
|
} FormData_pg_cast;
|
||||||
|
|
||||||
typedef FormData_pg_cast *Form_pg_cast;
|
typedef FormData_pg_cast *Form_pg_cast;
|
||||||
@ -56,16 +57,29 @@ typedef enum CoercionCodes
|
|||||||
COERCION_CODE_EXPLICIT = 'e' /* explicit cast operation */
|
COERCION_CODE_EXPLICIT = 'e' /* explicit cast operation */
|
||||||
} CoercionCodes;
|
} CoercionCodes;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The allowable values for pg_cast.castmethod are specified by this enum.
|
||||||
|
* Since castcontext is stored as a "char", we use ASCII codes for human
|
||||||
|
* convenience in reading the table.
|
||||||
|
*/
|
||||||
|
typedef enum CoercionMethod
|
||||||
|
{
|
||||||
|
COERCION_METHOD_FUNCTION = 'f', /* use a function */
|
||||||
|
COERCION_METHOD_BINARY = 'b', /* types are binary-compatible */
|
||||||
|
COERCION_METHOD_INOUT = 'i' /* use input/output functions */
|
||||||
|
} CoercionMethod;
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* compiler constants for pg_cast
|
* compiler constants for pg_cast
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
#define Natts_pg_cast 4
|
#define Natts_pg_cast 5
|
||||||
#define Anum_pg_cast_castsource 1
|
#define Anum_pg_cast_castsource 1
|
||||||
#define Anum_pg_cast_casttarget 2
|
#define Anum_pg_cast_casttarget 2
|
||||||
#define Anum_pg_cast_castfunc 3
|
#define Anum_pg_cast_castfunc 3
|
||||||
#define Anum_pg_cast_castcontext 4
|
#define Anum_pg_cast_castcontext 4
|
||||||
|
#define Anum_pg_cast_castmethod 5
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initial contents of pg_cast
|
* initial contents of pg_cast
|
||||||
@ -80,40 +94,40 @@ typedef enum CoercionCodes
|
|||||||
* int2->int4->int8->numeric->float4->float8, while casts in the
|
* int2->int4->int8->numeric->float4->float8, while casts in the
|
||||||
* reverse direction are assignment-only.
|
* reverse direction are assignment-only.
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 20 21 714 a ));
|
DATA(insert ( 20 21 714 a f ));
|
||||||
DATA(insert ( 20 23 480 a ));
|
DATA(insert ( 20 23 480 a f ));
|
||||||
DATA(insert ( 20 700 652 i ));
|
DATA(insert ( 20 700 652 i f ));
|
||||||
DATA(insert ( 20 701 482 i ));
|
DATA(insert ( 20 701 482 i f ));
|
||||||
DATA(insert ( 20 1700 1781 i ));
|
DATA(insert ( 20 1700 1781 i f ));
|
||||||
DATA(insert ( 21 20 754 i ));
|
DATA(insert ( 21 20 754 i f ));
|
||||||
DATA(insert ( 21 23 313 i ));
|
DATA(insert ( 21 23 313 i f ));
|
||||||
DATA(insert ( 21 700 236 i ));
|
DATA(insert ( 21 700 236 i f ));
|
||||||
DATA(insert ( 21 701 235 i ));
|
DATA(insert ( 21 701 235 i f ));
|
||||||
DATA(insert ( 21 1700 1782 i ));
|
DATA(insert ( 21 1700 1782 i f ));
|
||||||
DATA(insert ( 23 20 481 i ));
|
DATA(insert ( 23 20 481 i f ));
|
||||||
DATA(insert ( 23 21 314 a ));
|
DATA(insert ( 23 21 314 a f ));
|
||||||
DATA(insert ( 23 700 318 i ));
|
DATA(insert ( 23 700 318 i f ));
|
||||||
DATA(insert ( 23 701 316 i ));
|
DATA(insert ( 23 701 316 i f ));
|
||||||
DATA(insert ( 23 1700 1740 i ));
|
DATA(insert ( 23 1700 1740 i f ));
|
||||||
DATA(insert ( 700 20 653 a ));
|
DATA(insert ( 700 20 653 a f ));
|
||||||
DATA(insert ( 700 21 238 a ));
|
DATA(insert ( 700 21 238 a f ));
|
||||||
DATA(insert ( 700 23 319 a ));
|
DATA(insert ( 700 23 319 a f ));
|
||||||
DATA(insert ( 700 701 311 i ));
|
DATA(insert ( 700 701 311 i f ));
|
||||||
DATA(insert ( 700 1700 1742 a ));
|
DATA(insert ( 700 1700 1742 a f ));
|
||||||
DATA(insert ( 701 20 483 a ));
|
DATA(insert ( 701 20 483 a f ));
|
||||||
DATA(insert ( 701 21 237 a ));
|
DATA(insert ( 701 21 237 a f ));
|
||||||
DATA(insert ( 701 23 317 a ));
|
DATA(insert ( 701 23 317 a f ));
|
||||||
DATA(insert ( 701 700 312 a ));
|
DATA(insert ( 701 700 312 a f ));
|
||||||
DATA(insert ( 701 1700 1743 a ));
|
DATA(insert ( 701 1700 1743 a f ));
|
||||||
DATA(insert ( 1700 20 1779 a ));
|
DATA(insert ( 1700 20 1779 a f ));
|
||||||
DATA(insert ( 1700 21 1783 a ));
|
DATA(insert ( 1700 21 1783 a f ));
|
||||||
DATA(insert ( 1700 23 1744 a ));
|
DATA(insert ( 1700 23 1744 a f ));
|
||||||
DATA(insert ( 1700 700 1745 i ));
|
DATA(insert ( 1700 700 1745 i f ));
|
||||||
DATA(insert ( 1700 701 1746 i ));
|
DATA(insert ( 1700 701 1746 i f ));
|
||||||
|
|
||||||
/* Allow explicit coercions between int4 and bool */
|
/* Allow explicit coercions between int4 and bool */
|
||||||
DATA(insert ( 23 16 2557 e ));
|
DATA(insert ( 23 16 2557 e f ));
|
||||||
DATA(insert ( 16 23 2558 e ));
|
DATA(insert ( 16 23 2558 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OID category: allow implicit conversion from any integral type (including
|
* OID category: allow implicit conversion from any integral type (including
|
||||||
@ -125,164 +139,164 @@ DATA(insert ( 16 23 2558 e ));
|
|||||||
* casts from text and varchar to regclass, which exist mainly to support
|
* casts from text and varchar to regclass, which exist mainly to support
|
||||||
* legacy forms of nextval() and related functions.
|
* legacy forms of nextval() and related functions.
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 20 26 1287 i ));
|
DATA(insert ( 20 26 1287 i f ));
|
||||||
DATA(insert ( 21 26 313 i ));
|
DATA(insert ( 21 26 313 i f ));
|
||||||
DATA(insert ( 23 26 0 i ));
|
DATA(insert ( 23 26 0 i b ));
|
||||||
DATA(insert ( 26 20 1288 a ));
|
DATA(insert ( 26 20 1288 a f ));
|
||||||
DATA(insert ( 26 23 0 a ));
|
DATA(insert ( 26 23 0 a b ));
|
||||||
DATA(insert ( 26 24 0 i ));
|
DATA(insert ( 26 24 0 i b ));
|
||||||
DATA(insert ( 24 26 0 i ));
|
DATA(insert ( 24 26 0 i b ));
|
||||||
DATA(insert ( 20 24 1287 i ));
|
DATA(insert ( 20 24 1287 i f ));
|
||||||
DATA(insert ( 21 24 313 i ));
|
DATA(insert ( 21 24 313 i f ));
|
||||||
DATA(insert ( 23 24 0 i ));
|
DATA(insert ( 23 24 0 i b ));
|
||||||
DATA(insert ( 24 20 1288 a ));
|
DATA(insert ( 24 20 1288 a f ));
|
||||||
DATA(insert ( 24 23 0 a ));
|
DATA(insert ( 24 23 0 a b ));
|
||||||
DATA(insert ( 24 2202 0 i ));
|
DATA(insert ( 24 2202 0 i b ));
|
||||||
DATA(insert ( 2202 24 0 i ));
|
DATA(insert ( 2202 24 0 i b ));
|
||||||
DATA(insert ( 26 2202 0 i ));
|
DATA(insert ( 26 2202 0 i b ));
|
||||||
DATA(insert ( 2202 26 0 i ));
|
DATA(insert ( 2202 26 0 i b ));
|
||||||
DATA(insert ( 20 2202 1287 i ));
|
DATA(insert ( 20 2202 1287 i f ));
|
||||||
DATA(insert ( 21 2202 313 i ));
|
DATA(insert ( 21 2202 313 i f ));
|
||||||
DATA(insert ( 23 2202 0 i ));
|
DATA(insert ( 23 2202 0 i b ));
|
||||||
DATA(insert ( 2202 20 1288 a ));
|
DATA(insert ( 2202 20 1288 a f ));
|
||||||
DATA(insert ( 2202 23 0 a ));
|
DATA(insert ( 2202 23 0 a b ));
|
||||||
DATA(insert ( 26 2203 0 i ));
|
DATA(insert ( 26 2203 0 i b ));
|
||||||
DATA(insert ( 2203 26 0 i ));
|
DATA(insert ( 2203 26 0 i b ));
|
||||||
DATA(insert ( 20 2203 1287 i ));
|
DATA(insert ( 20 2203 1287 i f ));
|
||||||
DATA(insert ( 21 2203 313 i ));
|
DATA(insert ( 21 2203 313 i f ));
|
||||||
DATA(insert ( 23 2203 0 i ));
|
DATA(insert ( 23 2203 0 i b ));
|
||||||
DATA(insert ( 2203 20 1288 a ));
|
DATA(insert ( 2203 20 1288 a f ));
|
||||||
DATA(insert ( 2203 23 0 a ));
|
DATA(insert ( 2203 23 0 a b ));
|
||||||
DATA(insert ( 2203 2204 0 i ));
|
DATA(insert ( 2203 2204 0 i b ));
|
||||||
DATA(insert ( 2204 2203 0 i ));
|
DATA(insert ( 2204 2203 0 i b ));
|
||||||
DATA(insert ( 26 2204 0 i ));
|
DATA(insert ( 26 2204 0 i b ));
|
||||||
DATA(insert ( 2204 26 0 i ));
|
DATA(insert ( 2204 26 0 i b ));
|
||||||
DATA(insert ( 20 2204 1287 i ));
|
DATA(insert ( 20 2204 1287 i f ));
|
||||||
DATA(insert ( 21 2204 313 i ));
|
DATA(insert ( 21 2204 313 i f ));
|
||||||
DATA(insert ( 23 2204 0 i ));
|
DATA(insert ( 23 2204 0 i b ));
|
||||||
DATA(insert ( 2204 20 1288 a ));
|
DATA(insert ( 2204 20 1288 a f ));
|
||||||
DATA(insert ( 2204 23 0 a ));
|
DATA(insert ( 2204 23 0 a b ));
|
||||||
DATA(insert ( 26 2205 0 i ));
|
DATA(insert ( 26 2205 0 i b ));
|
||||||
DATA(insert ( 2205 26 0 i ));
|
DATA(insert ( 2205 26 0 i b ));
|
||||||
DATA(insert ( 20 2205 1287 i ));
|
DATA(insert ( 20 2205 1287 i f ));
|
||||||
DATA(insert ( 21 2205 313 i ));
|
DATA(insert ( 21 2205 313 i f ));
|
||||||
DATA(insert ( 23 2205 0 i ));
|
DATA(insert ( 23 2205 0 i b ));
|
||||||
DATA(insert ( 2205 20 1288 a ));
|
DATA(insert ( 2205 20 1288 a f ));
|
||||||
DATA(insert ( 2205 23 0 a ));
|
DATA(insert ( 2205 23 0 a b ));
|
||||||
DATA(insert ( 26 2206 0 i ));
|
DATA(insert ( 26 2206 0 i b ));
|
||||||
DATA(insert ( 2206 26 0 i ));
|
DATA(insert ( 2206 26 0 i b ));
|
||||||
DATA(insert ( 20 2206 1287 i ));
|
DATA(insert ( 20 2206 1287 i f ));
|
||||||
DATA(insert ( 21 2206 313 i ));
|
DATA(insert ( 21 2206 313 i f ));
|
||||||
DATA(insert ( 23 2206 0 i ));
|
DATA(insert ( 23 2206 0 i b ));
|
||||||
DATA(insert ( 2206 20 1288 a ));
|
DATA(insert ( 2206 20 1288 a f ));
|
||||||
DATA(insert ( 2206 23 0 a ));
|
DATA(insert ( 2206 23 0 a b ));
|
||||||
DATA(insert ( 26 3734 0 i ));
|
DATA(insert ( 26 3734 0 i b ));
|
||||||
DATA(insert ( 3734 26 0 i ));
|
DATA(insert ( 3734 26 0 i b ));
|
||||||
DATA(insert ( 20 3734 1287 i ));
|
DATA(insert ( 20 3734 1287 i f ));
|
||||||
DATA(insert ( 21 3734 313 i ));
|
DATA(insert ( 21 3734 313 i f ));
|
||||||
DATA(insert ( 23 3734 0 i ));
|
DATA(insert ( 23 3734 0 i b ));
|
||||||
DATA(insert ( 3734 20 1288 a ));
|
DATA(insert ( 3734 20 1288 a f ));
|
||||||
DATA(insert ( 3734 23 0 a ));
|
DATA(insert ( 3734 23 0 a b ));
|
||||||
DATA(insert ( 26 3769 0 i ));
|
DATA(insert ( 26 3769 0 i b ));
|
||||||
DATA(insert ( 3769 26 0 i ));
|
DATA(insert ( 3769 26 0 i b ));
|
||||||
DATA(insert ( 20 3769 1287 i ));
|
DATA(insert ( 20 3769 1287 i f ));
|
||||||
DATA(insert ( 21 3769 313 i ));
|
DATA(insert ( 21 3769 313 i f ));
|
||||||
DATA(insert ( 23 3769 0 i ));
|
DATA(insert ( 23 3769 0 i b ));
|
||||||
DATA(insert ( 3769 20 1288 a ));
|
DATA(insert ( 3769 20 1288 a f ));
|
||||||
DATA(insert ( 3769 23 0 a ));
|
DATA(insert ( 3769 23 0 a b ));
|
||||||
DATA(insert ( 25 2205 1079 i ));
|
DATA(insert ( 25 2205 1079 i f ));
|
||||||
DATA(insert ( 1043 2205 1079 i ));
|
DATA(insert ( 1043 2205 1079 i f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* String category
|
* String category
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 25 1042 0 i ));
|
DATA(insert ( 25 1042 0 i b ));
|
||||||
DATA(insert ( 25 1043 0 i ));
|
DATA(insert ( 25 1043 0 i b ));
|
||||||
DATA(insert ( 1042 25 401 i ));
|
DATA(insert ( 1042 25 401 i f ));
|
||||||
DATA(insert ( 1042 1043 401 i ));
|
DATA(insert ( 1042 1043 401 i f ));
|
||||||
DATA(insert ( 1043 25 0 i ));
|
DATA(insert ( 1043 25 0 i b ));
|
||||||
DATA(insert ( 1043 1042 0 i ));
|
DATA(insert ( 1043 1042 0 i b ));
|
||||||
DATA(insert ( 18 25 946 i ));
|
DATA(insert ( 18 25 946 i f ));
|
||||||
DATA(insert ( 18 1042 860 a ));
|
DATA(insert ( 18 1042 860 a f ));
|
||||||
DATA(insert ( 18 1043 946 a ));
|
DATA(insert ( 18 1043 946 a f ));
|
||||||
DATA(insert ( 19 25 406 i ));
|
DATA(insert ( 19 25 406 i f ));
|
||||||
DATA(insert ( 19 1042 408 a ));
|
DATA(insert ( 19 1042 408 a f ));
|
||||||
DATA(insert ( 19 1043 1401 a ));
|
DATA(insert ( 19 1043 1401 a f ));
|
||||||
DATA(insert ( 25 18 944 a ));
|
DATA(insert ( 25 18 944 a f ));
|
||||||
DATA(insert ( 1042 18 944 a ));
|
DATA(insert ( 1042 18 944 a f ));
|
||||||
DATA(insert ( 1043 18 944 a ));
|
DATA(insert ( 1043 18 944 a f ));
|
||||||
DATA(insert ( 25 19 407 i ));
|
DATA(insert ( 25 19 407 i f ));
|
||||||
DATA(insert ( 1042 19 409 i ));
|
DATA(insert ( 1042 19 409 i f ));
|
||||||
DATA(insert ( 1043 19 1400 i ));
|
DATA(insert ( 1043 19 1400 i f ));
|
||||||
|
|
||||||
/* Allow explicit coercions between int4 and "char" */
|
/* Allow explicit coercions between int4 and "char" */
|
||||||
DATA(insert ( 18 23 77 e ));
|
DATA(insert ( 18 23 77 e f ));
|
||||||
DATA(insert ( 23 18 78 e ));
|
DATA(insert ( 23 18 78 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Datetime category
|
* Datetime category
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 702 1082 1179 a ));
|
DATA(insert ( 702 1082 1179 a f ));
|
||||||
DATA(insert ( 702 1083 1364 a ));
|
DATA(insert ( 702 1083 1364 a f ));
|
||||||
DATA(insert ( 702 1114 2023 i ));
|
DATA(insert ( 702 1114 2023 i f ));
|
||||||
DATA(insert ( 702 1184 1173 i ));
|
DATA(insert ( 702 1184 1173 i f ));
|
||||||
DATA(insert ( 703 1186 1177 i ));
|
DATA(insert ( 703 1186 1177 i f ));
|
||||||
DATA(insert ( 1082 1114 2024 i ));
|
DATA(insert ( 1082 1114 2024 i f ));
|
||||||
DATA(insert ( 1082 1184 1174 i ));
|
DATA(insert ( 1082 1184 1174 i f ));
|
||||||
DATA(insert ( 1083 1186 1370 i ));
|
DATA(insert ( 1083 1186 1370 i f ));
|
||||||
DATA(insert ( 1083 1266 2047 i ));
|
DATA(insert ( 1083 1266 2047 i f ));
|
||||||
DATA(insert ( 1114 702 2030 a ));
|
DATA(insert ( 1114 702 2030 a f ));
|
||||||
DATA(insert ( 1114 1082 2029 a ));
|
DATA(insert ( 1114 1082 2029 a f ));
|
||||||
DATA(insert ( 1114 1083 1316 a ));
|
DATA(insert ( 1114 1083 1316 a f ));
|
||||||
DATA(insert ( 1114 1184 2028 i ));
|
DATA(insert ( 1114 1184 2028 i f ));
|
||||||
DATA(insert ( 1184 702 1180 a ));
|
DATA(insert ( 1184 702 1180 a f ));
|
||||||
DATA(insert ( 1184 1082 1178 a ));
|
DATA(insert ( 1184 1082 1178 a f ));
|
||||||
DATA(insert ( 1184 1083 2019 a ));
|
DATA(insert ( 1184 1083 2019 a f ));
|
||||||
DATA(insert ( 1184 1114 2027 a ));
|
DATA(insert ( 1184 1114 2027 a f ));
|
||||||
DATA(insert ( 1184 1266 1388 a ));
|
DATA(insert ( 1184 1266 1388 a f ));
|
||||||
DATA(insert ( 1186 703 1194 a ));
|
DATA(insert ( 1186 703 1194 a f ));
|
||||||
DATA(insert ( 1186 1083 1419 a ));
|
DATA(insert ( 1186 1083 1419 a f ));
|
||||||
DATA(insert ( 1266 1083 2046 a ));
|
DATA(insert ( 1266 1083 2046 a f ));
|
||||||
/* Cross-category casts between int4 and abstime, reltime */
|
/* Cross-category casts between int4 and abstime, reltime */
|
||||||
DATA(insert ( 23 702 0 e ));
|
DATA(insert ( 23 702 0 e b ));
|
||||||
DATA(insert ( 702 23 0 e ));
|
DATA(insert ( 702 23 0 e b ));
|
||||||
DATA(insert ( 23 703 0 e ));
|
DATA(insert ( 23 703 0 e b ));
|
||||||
DATA(insert ( 703 23 0 e ));
|
DATA(insert ( 703 23 0 e b ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Geometric category
|
* Geometric category
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 601 600 1532 e ));
|
DATA(insert ( 601 600 1532 e f ));
|
||||||
DATA(insert ( 602 600 1533 e ));
|
DATA(insert ( 602 600 1533 e f ));
|
||||||
DATA(insert ( 602 604 1449 a ));
|
DATA(insert ( 602 604 1449 a f ));
|
||||||
DATA(insert ( 603 600 1534 e ));
|
DATA(insert ( 603 600 1534 e f ));
|
||||||
DATA(insert ( 603 601 1541 e ));
|
DATA(insert ( 603 601 1541 e f ));
|
||||||
DATA(insert ( 603 604 1448 a ));
|
DATA(insert ( 603 604 1448 a f ));
|
||||||
DATA(insert ( 603 718 1479 e ));
|
DATA(insert ( 603 718 1479 e f ));
|
||||||
DATA(insert ( 604 600 1540 e ));
|
DATA(insert ( 604 600 1540 e f ));
|
||||||
DATA(insert ( 604 602 1447 a ));
|
DATA(insert ( 604 602 1447 a f ));
|
||||||
DATA(insert ( 604 603 1446 e ));
|
DATA(insert ( 604 603 1446 e f ));
|
||||||
DATA(insert ( 604 718 1474 e ));
|
DATA(insert ( 604 718 1474 e f ));
|
||||||
DATA(insert ( 718 600 1416 e ));
|
DATA(insert ( 718 600 1416 e f ));
|
||||||
DATA(insert ( 718 603 1480 e ));
|
DATA(insert ( 718 603 1480 e f ));
|
||||||
DATA(insert ( 718 604 1544 e ));
|
DATA(insert ( 718 604 1544 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INET category
|
* INET category
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 650 869 0 i ));
|
DATA(insert ( 650 869 0 i b ));
|
||||||
DATA(insert ( 869 650 1715 a ));
|
DATA(insert ( 869 650 1715 a f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BitString category
|
* BitString category
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 1560 1562 0 i ));
|
DATA(insert ( 1560 1562 0 i b ));
|
||||||
DATA(insert ( 1562 1560 0 i ));
|
DATA(insert ( 1562 1560 0 i b ));
|
||||||
/* Cross-category casts between bit and int4, int8 */
|
/* Cross-category casts between bit and int4, int8 */
|
||||||
DATA(insert ( 20 1560 2075 e ));
|
DATA(insert ( 20 1560 2075 e f ));
|
||||||
DATA(insert ( 23 1560 1683 e ));
|
DATA(insert ( 23 1560 1683 e f ));
|
||||||
DATA(insert ( 1560 20 2076 e ));
|
DATA(insert ( 1560 20 2076 e f ));
|
||||||
DATA(insert ( 1560 23 1684 e ));
|
DATA(insert ( 1560 23 1684 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cross-category casts to and from TEXT
|
* Cross-category casts to and from TEXT
|
||||||
@ -296,46 +310,46 @@ DATA(insert ( 1560 23 1684 e ));
|
|||||||
* behavior will ensue when the automatic cast is applied instead of the
|
* behavior will ensue when the automatic cast is applied instead of the
|
||||||
* pg_cast entry!
|
* pg_cast entry!
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 650 25 730 a ));
|
DATA(insert ( 650 25 730 a f ));
|
||||||
DATA(insert ( 869 25 730 a ));
|
DATA(insert ( 869 25 730 a f ));
|
||||||
DATA(insert ( 16 25 2971 a ));
|
DATA(insert ( 16 25 2971 a f ));
|
||||||
DATA(insert ( 142 25 0 a ));
|
DATA(insert ( 142 25 0 a b ));
|
||||||
DATA(insert ( 25 142 2896 e ));
|
DATA(insert ( 25 142 2896 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cross-category casts to and from VARCHAR
|
* Cross-category casts to and from VARCHAR
|
||||||
*
|
*
|
||||||
* We support all the same casts as for TEXT.
|
* We support all the same casts as for TEXT.
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 650 1043 730 a ));
|
DATA(insert ( 650 1043 730 a f ));
|
||||||
DATA(insert ( 869 1043 730 a ));
|
DATA(insert ( 869 1043 730 a f ));
|
||||||
DATA(insert ( 16 1043 2971 a ));
|
DATA(insert ( 16 1043 2971 a f ));
|
||||||
DATA(insert ( 142 1043 0 a ));
|
DATA(insert ( 142 1043 0 a b ));
|
||||||
DATA(insert ( 1043 142 2896 e ));
|
DATA(insert ( 1043 142 2896 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cross-category casts to and from BPCHAR
|
* Cross-category casts to and from BPCHAR
|
||||||
*
|
*
|
||||||
* We support all the same casts as for TEXT.
|
* We support all the same casts as for TEXT.
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 650 1042 730 a ));
|
DATA(insert ( 650 1042 730 a f ));
|
||||||
DATA(insert ( 869 1042 730 a ));
|
DATA(insert ( 869 1042 730 a f ));
|
||||||
DATA(insert ( 16 1042 2971 a ));
|
DATA(insert ( 16 1042 2971 a f ));
|
||||||
DATA(insert ( 142 1042 0 a ));
|
DATA(insert ( 142 1042 0 a b ));
|
||||||
DATA(insert ( 1042 142 2896 e ));
|
DATA(insert ( 1042 142 2896 e f ));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Length-coercion functions
|
* Length-coercion functions
|
||||||
*/
|
*/
|
||||||
DATA(insert ( 1042 1042 668 i ));
|
DATA(insert ( 1042 1042 668 i f ));
|
||||||
DATA(insert ( 1043 1043 669 i ));
|
DATA(insert ( 1043 1043 669 i f ));
|
||||||
DATA(insert ( 1083 1083 1968 i ));
|
DATA(insert ( 1083 1083 1968 i f ));
|
||||||
DATA(insert ( 1114 1114 1961 i ));
|
DATA(insert ( 1114 1114 1961 i f ));
|
||||||
DATA(insert ( 1184 1184 1967 i ));
|
DATA(insert ( 1184 1184 1967 i f ));
|
||||||
DATA(insert ( 1186 1186 1200 i ));
|
DATA(insert ( 1186 1186 1200 i f ));
|
||||||
DATA(insert ( 1266 1266 1969 i ));
|
DATA(insert ( 1266 1266 1969 i f ));
|
||||||
DATA(insert ( 1560 1560 1685 i ));
|
DATA(insert ( 1560 1560 1685 i f ));
|
||||||
DATA(insert ( 1562 1562 1687 i ));
|
DATA(insert ( 1562 1562 1687 i f ));
|
||||||
DATA(insert ( 1700 1700 1703 i ));
|
DATA(insert ( 1700 1700 1703 i f ));
|
||||||
|
|
||||||
#endif /* PG_CAST_H */
|
#endif /* PG_CAST_H */
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.376 2008/10/04 21:56:55 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.377 2008/10/31 08:39:22 heikki Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2062,6 +2062,7 @@ typedef struct CreateCastStmt
|
|||||||
TypeName *targettype;
|
TypeName *targettype;
|
||||||
FuncWithArgs *func;
|
FuncWithArgs *func;
|
||||||
CoercionContext context;
|
CoercionContext context;
|
||||||
|
bool inout;
|
||||||
} CreateCastStmt;
|
} CreateCastStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
|
@ -22,7 +22,7 @@ create function binary_coercible(oid, oid) returns bool as $$
|
|||||||
SELECT ($1 = $2) OR
|
SELECT ($1 = $2) OR
|
||||||
EXISTS(select 1 from pg_catalog.pg_cast where
|
EXISTS(select 1 from pg_catalog.pg_cast where
|
||||||
castsource = $1 and casttarget = $2 and
|
castsource = $1 and casttarget = $2 and
|
||||||
castfunc = 0 and castcontext = 'i') OR
|
castmethod = 'b' and castcontext = 'i') OR
|
||||||
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
||||||
EXISTS(select 1 from pg_catalog.pg_type where
|
EXISTS(select 1 from pg_catalog.pg_type where
|
||||||
oid = $1 and typelem != 0 and typlen = -1))
|
oid = $1 and typelem != 0 and typlen = -1))
|
||||||
@ -33,7 +33,7 @@ create function physically_coercible(oid, oid) returns bool as $$
|
|||||||
SELECT ($1 = $2) OR
|
SELECT ($1 = $2) OR
|
||||||
EXISTS(select 1 from pg_catalog.pg_cast where
|
EXISTS(select 1 from pg_catalog.pg_cast where
|
||||||
castsource = $1 and casttarget = $2 and
|
castsource = $1 and casttarget = $2 and
|
||||||
castfunc = 0) OR
|
castmethod = 'b') OR
|
||||||
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
||||||
EXISTS(select 1 from pg_catalog.pg_type where
|
EXISTS(select 1 from pg_catalog.pg_type where
|
||||||
oid = $1 and typelem != 0 and typlen = -1))
|
oid = $1 and typelem != 0 and typlen = -1))
|
||||||
@ -262,9 +262,20 @@ WHERE p1.prorettype = 'internal'::regtype AND NOT
|
|||||||
-- oidjoins test).
|
-- oidjoins test).
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i');
|
WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
|
||||||
castsource | casttarget | castfunc | castcontext
|
OR castmethod NOT IN ('f', 'b' ,'i');
|
||||||
------------+------------+----------+-------------
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
|
------------+------------+----------+-------------+------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- Check that castfunc is nonzero only for cast methods that need a function,
|
||||||
|
-- and zero otherwise
|
||||||
|
SELECT *
|
||||||
|
FROM pg_cast c
|
||||||
|
WHERE (castmethod = 'f' AND castfunc = 0)
|
||||||
|
OR (castmethod IN ('b', 'i') AND castfunc <> 0);
|
||||||
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
|
------------+------------+----------+-------------+------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Look for casts to/from the same type that aren't length coercion functions.
|
-- Look for casts to/from the same type that aren't length coercion functions.
|
||||||
@ -273,15 +284,15 @@ WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i');
|
|||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE castsource = casttarget AND castfunc = 0;
|
WHERE castsource = casttarget AND castfunc = 0;
|
||||||
castsource | casttarget | castfunc | castcontext
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
------------+------------+----------+-------------
|
------------+------------+----------+-------------+------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
SELECT c.*
|
SELECT c.*
|
||||||
FROM pg_cast c, pg_proc p
|
FROM pg_cast c, pg_proc p
|
||||||
WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget;
|
WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget;
|
||||||
castsource | casttarget | castfunc | castcontext
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
------------+------------+----------+-------------
|
------------+------------+----------+-------------+------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Look for cast functions that don't have the right signature. The
|
-- Look for cast functions that don't have the right signature. The
|
||||||
@ -299,8 +310,8 @@ WHERE c.castfunc = p.oid AND
|
|||||||
OR (c.castsource = 'character'::regtype AND
|
OR (c.castsource = 'character'::regtype AND
|
||||||
p.proargtypes[0] = 'text'::regtype))
|
p.proargtypes[0] = 'text'::regtype))
|
||||||
OR NOT binary_coercible(p.prorettype, c.casttarget));
|
OR NOT binary_coercible(p.prorettype, c.casttarget));
|
||||||
castsource | casttarget | castfunc | castcontext
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
------------+------------+----------+-------------
|
------------+------------+----------+-------------+------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
SELECT c.*
|
SELECT c.*
|
||||||
@ -308,8 +319,8 @@ FROM pg_cast c, pg_proc p
|
|||||||
WHERE c.castfunc = p.oid AND
|
WHERE c.castfunc = p.oid AND
|
||||||
((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR
|
((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR
|
||||||
(p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype));
|
(p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype));
|
||||||
castsource | casttarget | castfunc | castcontext
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
------------+------------+----------+-------------
|
------------+------------+----------+-------------+------------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- Look for binary compatible casts that do not have the reverse
|
-- Look for binary compatible casts that do not have the reverse
|
||||||
@ -324,19 +335,19 @@ WHERE c.castfunc = p.oid AND
|
|||||||
-- texttoxml(), which does an XML syntax check.
|
-- texttoxml(), which does an XML syntax check.
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE c.castfunc = 0 AND
|
WHERE c.castmethod = 'b' AND
|
||||||
NOT EXISTS (SELECT 1 FROM pg_cast k
|
NOT EXISTS (SELECT 1 FROM pg_cast k
|
||||||
WHERE k.castfunc = 0 AND
|
WHERE k.castmethod = 'b' AND
|
||||||
k.castsource = c.casttarget AND
|
k.castsource = c.casttarget AND
|
||||||
k.casttarget = c.castsource);
|
k.casttarget = c.castsource);
|
||||||
castsource | casttarget | castfunc | castcontext
|
castsource | casttarget | castfunc | castcontext | castmethod
|
||||||
------------+------------+----------+-------------
|
------------+------------+----------+-------------+------------
|
||||||
25 | 1042 | 0 | i
|
25 | 1042 | 0 | i | b
|
||||||
1043 | 1042 | 0 | i
|
1043 | 1042 | 0 | i | b
|
||||||
650 | 869 | 0 | i
|
650 | 869 | 0 | i | b
|
||||||
142 | 25 | 0 | a
|
142 | 25 | 0 | a | b
|
||||||
142 | 1043 | 0 | a
|
142 | 1043 | 0 | a | b
|
||||||
142 | 1042 | 0 | a
|
142 | 1042 | 0 | a | b
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
|
||||||
-- **************** pg_operator ****************
|
-- **************** pg_operator ****************
|
||||||
|
@ -25,7 +25,7 @@ create function binary_coercible(oid, oid) returns bool as $$
|
|||||||
SELECT ($1 = $2) OR
|
SELECT ($1 = $2) OR
|
||||||
EXISTS(select 1 from pg_catalog.pg_cast where
|
EXISTS(select 1 from pg_catalog.pg_cast where
|
||||||
castsource = $1 and casttarget = $2 and
|
castsource = $1 and casttarget = $2 and
|
||||||
castfunc = 0 and castcontext = 'i') OR
|
castmethod = 'b' and castcontext = 'i') OR
|
||||||
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
||||||
EXISTS(select 1 from pg_catalog.pg_type where
|
EXISTS(select 1 from pg_catalog.pg_type where
|
||||||
oid = $1 and typelem != 0 and typlen = -1))
|
oid = $1 and typelem != 0 and typlen = -1))
|
||||||
@ -37,7 +37,7 @@ create function physically_coercible(oid, oid) returns bool as $$
|
|||||||
SELECT ($1 = $2) OR
|
SELECT ($1 = $2) OR
|
||||||
EXISTS(select 1 from pg_catalog.pg_cast where
|
EXISTS(select 1 from pg_catalog.pg_cast where
|
||||||
castsource = $1 and casttarget = $2 and
|
castsource = $1 and casttarget = $2 and
|
||||||
castfunc = 0) OR
|
castmethod = 'b') OR
|
||||||
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
|
||||||
EXISTS(select 1 from pg_catalog.pg_type where
|
EXISTS(select 1 from pg_catalog.pg_type where
|
||||||
oid = $1 and typelem != 0 and typlen = -1))
|
oid = $1 and typelem != 0 and typlen = -1))
|
||||||
@ -214,7 +214,16 @@ WHERE p1.prorettype = 'internal'::regtype AND NOT
|
|||||||
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i');
|
WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
|
||||||
|
OR castmethod NOT IN ('f', 'b' ,'i');
|
||||||
|
|
||||||
|
-- Check that castfunc is nonzero only for cast methods that need a function,
|
||||||
|
-- and zero otherwise
|
||||||
|
|
||||||
|
SELECT *
|
||||||
|
FROM pg_cast c
|
||||||
|
WHERE (castmethod = 'f' AND castfunc = 0)
|
||||||
|
OR (castmethod IN ('b', 'i') AND castfunc <> 0);
|
||||||
|
|
||||||
-- Look for casts to/from the same type that aren't length coercion functions.
|
-- Look for casts to/from the same type that aren't length coercion functions.
|
||||||
-- (We assume they are length coercions if they take multiple arguments.)
|
-- (We assume they are length coercions if they take multiple arguments.)
|
||||||
@ -267,9 +276,9 @@ WHERE c.castfunc = p.oid AND
|
|||||||
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM pg_cast c
|
FROM pg_cast c
|
||||||
WHERE c.castfunc = 0 AND
|
WHERE c.castmethod = 'b' AND
|
||||||
NOT EXISTS (SELECT 1 FROM pg_cast k
|
NOT EXISTS (SELECT 1 FROM pg_cast k
|
||||||
WHERE k.castfunc = 0 AND
|
WHERE k.castmethod = 'b' AND
|
||||||
k.castsource = c.casttarget AND
|
k.castsource = c.casttarget AND
|
||||||
k.casttarget = c.castsource);
|
k.casttarget = c.castsource);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user