Hello,
Please find attached a minor stylish patch. It compiles and the update
test cases work for me.
Description:
Add "AS EXPLICIT" to "CREATE CAST"
This gives a name to the default case of "CREATE CAST", which creates a
cast which must be explicitely invoked.
From a language definition perspective, it is helpful to have a name for
every case instead of an implicit fallback, without any word to describe
it. See for instance "CREATE USER CREATEDB/NOCREATEDB" or "CREATE RULE ...
DO ALSO/INSTEAD" for similar occurences of naming default cases.
--
Fabien.
diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml
index c0039ed..35893b7 100644
--- a/doc/src/sgml/ref/create_cast.sgml
+++ b/doc/src/sgml/ref/create_cast.sgml
@@ -20,15 +20,15 @@
<synopsis>
CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
WITH FUNCTION <replaceable>function_name</replaceable> (<replaceable>argument_type</replaceable> [, ...])
- [ AS ASSIGNMENT | AS IMPLICIT ]
+ [ AS ASSIGNMENT | AS EXPLICIT | AS IMPLICIT ]
CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
WITHOUT FUNCTION
- [ AS ASSIGNMENT | AS IMPLICIT ]
+ [ AS ASSIGNMENT | AS EXPLICIT | AS IMPLICIT ]
CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
WITH INOUT
- [ AS ASSIGNMENT | AS IMPLICIT ]
+ [ AS ASSIGNMENT | AS EXPLICIT | AS IMPLICIT ]
</synopsis>
</refsynopsisdiv>
@@ -74,7 +74,8 @@ SELECT CAST(42 AS float8);
</para>
<para>
- By default, a cast can be invoked only by an explicit cast request,
+ By default, or if the cast is declared <literal>AS EXPLICIT</>,
+ a cast can be invoked only by an explicit cast request,
that is an explicit <literal>CAST(<replaceable>x</> AS
<replaceable>typename</>)</literal> or
<replaceable>x</><literal>::</><replaceable>typename</>
@@ -238,6 +239,21 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
</varlistentry>
<varlistentry>
+ <term><literal>AS EXPLICIT</literal></term>
+
+ <listitem>
+ <para>
+ Indicates that the cast can be invoked only with an explicit
+ cast request, that is an explicit <literal>CAST(<replaceable>x</> AS
+ <replaceable>typename</>)</literal> or
+ <replaceable>x</><literal>::</><replaceable>typename</>
+ construct.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>AS IMPLICIT</literal></term>
<listitem>
@@ -405,8 +421,8 @@ CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
<acronym>SQL</acronym> standard,
except that SQL does not make provisions for binary-coercible
types or extra arguments to implementation functions.
- <literal>AS IMPLICIT</> is a <productname>PostgreSQL</productname>
- extension, too.
+ <literal>AS IMPLICIT</> and <literal>AS EXPLICIT</> are
+ a <productname>PostgreSQL</productname> extension, too.
</para>
</refsect1>
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1d39674..de339db 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -499,7 +499,7 @@ static void SplitColQualList(List *qualList,
DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT
- EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
+ EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXPLICIT
EXTENSION EXTERNAL EXTRACT
FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD
@@ -6313,6 +6313,7 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
cast_context: AS IMPLICIT_P { $$ = COERCION_IMPLICIT; }
| AS ASSIGNMENT { $$ = COERCION_ASSIGNMENT; }
+ | AS EXPLICIT { $$ = COERCION_EXPLICIT; }
| /*EMPTY*/ { $$ = COERCION_EXPLICIT; }
;
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 12c2faf..f5b2f16 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -148,6 +148,7 @@ PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD)
PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD)
PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD)
PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD)
+PG_KEYWORD("explicit", EXPLICIT, UNRESERVED_KEYWORD)
PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD)
PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD)
PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD)
diff --git a/src/test/regress/expected/create_cast.out b/src/test/regress/expected/create_cast.out
index 56cd86e..a8858fa 100644
--- a/src/test/regress/expected/create_cast.out
+++ b/src/test/regress/expected/create_cast.out
@@ -27,8 +27,8 @@ ERROR: function casttestfunc(text) does not exist
LINE 1: SELECT casttestfunc('foo'::text);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
--- Try binary coercion cast
-CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+-- Try binary coercion cast and verbose AS EXPLICIT
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS EXPLICIT;
SELECT casttestfunc('foo'::text); -- doesn't work, as the cast is explicit
ERROR: function casttestfunc(text) does not exist
LINE 1: SELECT casttestfunc('foo'::text);
@@ -54,7 +54,7 @@ SELECT 1234::int4::casttesttype; -- No cast yet, should fail
ERROR: cannot cast type integer to casttesttype
LINE 1: SELECT 1234::int4::casttesttype;
^
-CREATE CAST (int4 AS casttesttype) WITH INOUT;
+CREATE CAST (int4 AS casttesttype) WITH INOUT; -- default AS EXPLICIT
SELECT 1234::int4::casttesttype; -- Should work now
casttesttype
--------------
diff --git a/src/test/regress/sql/create_cast.sql b/src/test/regress/sql/create_cast.sql
index ad348da..91123ca 100644
--- a/src/test/regress/sql/create_cast.sql
+++ b/src/test/regress/sql/create_cast.sql
@@ -27,8 +27,8 @@ $$ SELECT 1; $$;
SELECT casttestfunc('foo'::text); -- fails, as there's no cast
--- Try binary coercion cast
-CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+-- Try binary coercion cast and verbose AS EXPLICIT
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS EXPLICIT;
SELECT casttestfunc('foo'::text); -- doesn't work, as the cast is explicit
SELECT casttestfunc('foo'::text::casttesttype); -- should work
DROP CAST (text AS casttesttype); -- cleanup
@@ -40,7 +40,7 @@ SELECT casttestfunc('foo'::text); -- Should work now
-- Try I/O conversion cast.
SELECT 1234::int4::casttesttype; -- No cast yet, should fail
-CREATE CAST (int4 AS casttesttype) WITH INOUT;
+CREATE CAST (int4 AS casttesttype) WITH INOUT; -- default AS EXPLICIT
SELECT 1234::int4::casttesttype; -- Should work now
DROP CAST (int4 AS casttesttype);
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers