diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index d0b34789cf157ada1bc7f7929122956915503fa5..de8e3456e15fda66708c605a643d51ad42fe93f1 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,4 +1,4 @@ - + @@ -1440,7 +1440,7 @@ pg_proc.oid The OID of the function to use to perform this cast. Zero is - stored if the data types are binary compatible (that is, no + stored if the data types are binary coercible (that is, no run-time operation is needed to perform the cast) diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml index c329c36b190cabdb40a83cb810169feeebe4bec1..2ef9a7978989748e15aa1a7a635d9b7d77540a30 100644 --- a/doc/src/sgml/ref/create_cast.sgml +++ b/doc/src/sgml/ref/create_cast.sgml @@ -1,4 +1,4 @@ - + @@ -44,12 +44,18 @@ SELECT CAST(42 AS float8); - Two types can be binary compatible, which - means that they can be converted into one another for - free without invoking any function. This requires that - corresponding values use the same internal representation. For - instance, the types text and varchar are - binary compatible. + Two types can be binary coercible, which + means that the conversion can be performed for free + without invoking any function. This requires that corresponding + values use the same internal representation. For instance, the + types text and varchar are binary + coercible both ways. Binary coercibility is not necessarily a + symmetric relationship. For example, the cast + from xml to text can be performed for + free in the present implementation, but the reverse direction + requires a function that performs at least a syntax check. (Two + types that are binary coercible both ways are also referred to as + binary compatible.) @@ -127,8 +133,8 @@ SELECT CAST ( 2 AS numeric ) + 4.0; To be able to create a cast, you must own the source or the target - data type. To create a binary-compatible cast, you must be superuser. - (This restriction is made because an erroneous binary-compatible cast + data type. To create a binary-coercible cast, you must be superuser. + (This restriction is made because an erroneous binary-coercible cast conversion can easily crash the server.) @@ -176,7 +182,7 @@ SELECT CAST ( 2 AS numeric ) + 4.0; Indicates that the source type and the target type are binary - compatible, so no function is required to perform the cast. + coercible, so no function is required to perform the cast. @@ -205,8 +211,8 @@ SELECT CAST ( 2 AS numeric ) + 4.0; Cast implementation functions can have one to three arguments. - The first argument type must be identical to the cast's source type. - The second argument, + The first argument type must be identical to or binary-coercible from + the cast's source type. The second argument, if present, must be type integer; it receives the type modifier associated with the destination type, or -1 if there is none. The third argument, @@ -218,6 +224,11 @@ SELECT CAST ( 2 AS numeric ) + 4.0; your own data types so that this matters.) + + The return type of a cast function must be identical to or + binary-coercible to the cast's target type. + + Ordinarily a cast must have different source and target data types. However, it is allowed to declare a cast with identical source and @@ -311,10 +322,10 @@ SELECT CAST ( 2 AS numeric ) + 4.0; request without having matched it to an actual function. If a function call name(x) does not exactly match any existing function, but name is the name - of a data type and pg_cast provides a binary-compatible cast + of a data type and pg_cast provides a binary-coercible cast to this type from the type of x, then the call will be construed as a binary-compatible cast. This exception is made so that - binary-compatible casts can be invoked using functional syntax, even + binary-coercible casts can be invoked using functional syntax, even though they lack any function. Likewise, if there is no pg_cast entry but the cast would be to or from a string type, the call will be construed as an I/O conversion cast. This @@ -345,7 +356,7 @@ CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint); The CREATE CAST command conforms to the SQL standard, - except that SQL does not make provisions for binary-compatible + except that SQL does not make provisions for binary-coercible types or extra arguments to implementation functions. AS IMPLICIT is a PostgreSQL extension, too. diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index 7cf3efdb1ae4018fd87cb7cdca078a06445ce111..451555cd022708b89f7c025e2a9746eafbe3e52a 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -1,4 +1,4 @@ - + Type Conversion @@ -522,7 +522,7 @@ If no exact match is found, see whether the function call appears to be a special type conversion request. This happens if the function call has just one argument and the function name is the same as the (internal) name of some data type. Furthermore, the function argument must be either -an unknown-type literal, or a type that is binary-compatible with the named +an unknown-type literal, or a type that is binary-coercible to the named data type, or a type that could be converted to the named data type by applying that type's I/O functions (that is, the conversion is either to or from one of the standard string types). When these conditions are met, @@ -783,8 +783,8 @@ to text by default, allowing the || operator to be resolved as text concatenation. Then the text result of the operator is converted to bpchar (blank-padded char, the internal name of the character data type) to match the target -column type. (Since the types text and -bpchar are binary-compatible, this conversion does +column type. (Since the conversion from text to +bpchar is binary-coercible, this conversion does not insert any real function call.) Finally, the sizing function bpchar(bpchar, integer) is found in the system catalog and applied to the operator's result and the stored column length. This diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 68d3a65db57fb46e6ccb31c8381cb6be3c21af08..abb2e6eca887140e3ee49f0559fce6dd206948be 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.93 2008/06/19 00:46:04 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.94 2008/07/11 07:02:43 petere Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -48,6 +48,7 @@ #include "commands/defrem.h" #include "commands/proclang.h" #include "miscadmin.h" +#include "parser/parse_coerce.h" #include "parser/parse_func.h" #include "parser/parse_type.h" #include "utils/acl.h" @@ -1403,10 +1404,10 @@ CreateCast(CreateCastStmt *stmt) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cast function must take one to three arguments"))); - if (procstruct->proargtypes.values[0] != sourcetypeid) + if (!IsBinaryCoercible(sourcetypeid, procstruct->proargtypes.values[0])) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("argument of cast function must match source data type"))); + errmsg("argument of cast function must match or be binary-compatible with source data type"))); if (nargs > 1 && procstruct->proargtypes.values[1] != INT4OID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), @@ -1415,10 +1416,10 @@ CreateCast(CreateCastStmt *stmt) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("third argument of cast function must be type boolean"))); - if (procstruct->prorettype != targettypeid) + if (!IsBinaryCoercible(procstruct->prorettype, targettypeid)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("return data type of cast function must match target data type"))); + errmsg("return data type of cast function must match or be binary-compatible with target data type"))); /* * Restricting the volatility of a cast function may or may not be a