pgsql.hackers
[Top] [All Lists]

User defined I/O conversion casts

Subject: User defined I/O conversion casts
From: Heikki Linnakangas
Date: Fri, 29 Aug 2008 13:59:01 +0300
Newsgroups: pgsql.hackers
Since 8.3, the system provides automatic I/O conversion casts between the built-in string types and other types, but there's currently no way for a user to declare additional casts using the I/O functions. You can always create a simple SQL function to do that, but it seems like we should provide a direct interface for that. I propose the syntax:

CREATE CAST (<source> AS <target>) WITH INOUT [AS IMPLICIT | AS ASSIGNMENT]

Conveniently, INOUT is already a col_name_keyword, so this works without any conflicts or new keywords.

This would be very useful for those who want relax some built-in automatic assignment casts to implicit casts, 8.2 style, as well as anyone creating a user-defined data type with casts that can be implemented with the I/O functions.

Patch attached. I'm using a magic OID "1" in pg_cast.castfunc field to mark these extra I/O conversion casts. Perhaps we want to have a separate field for that or something, but that was a quick way to get started.

Anyone else think this is a good idea? Thoughts on the implementation?

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
Index: src/backend/commands/functioncmds.c
===================================================================
RCS file: 
/home/hlinnaka/pgcvsrepository/pgsql/src/backend/commands/functioncmds.c,v
retrieving revision 1.98
diff -c -r1.98 functioncmds.c
*** src/backend/commands/functioncmds.c 18 Jul 2008 03:32:52 -0000      1.98
--- src/backend/commands/functioncmds.c 29 Aug 2008 10:56:49 -0000
***************
*** 1474,1479 ****
--- 1474,1481 ----
  
                ReleaseSysCache(tuple);
        }
+       else if (stmt->coerceviaio)
+               funcid = IOCOERCE_FUNCOID;
        else
        {
                int16           typ1len;
***************
*** 1589,1595 ****
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
  
        /* dependency on function */
!       if (OidIsValid(funcid))
        {
                referenced.classId = ProcedureRelationId;
                referenced.objectId = funcid;
--- 1591,1597 ----
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
  
        /* dependency on function */
!       if (OidIsValid(funcid) && funcid != IOCOERCE_FUNCOID)
        {
                referenced.classId = ProcedureRelationId;
                referenced.objectId = funcid;
Index: src/backend/parser/gram.y
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.618
diff -c -r2.618 gram.y
*** src/backend/parser/gram.y   18 Jul 2008 03:32:52 -0000      2.618
--- src/backend/parser/gram.y   29 Aug 2008 09:29:22 -0000
***************
*** 4534,4539 ****
--- 4534,4550 ----
                                        n->context = (CoercionContext) $10;
                                        $$ = (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->coerceviaio = true;
+                                       n->context = (CoercionContext) $10;
+                                       $$ = (Node *)n;
+                               }
                ;
  
  cast_context:  AS IMPLICIT_P                                  { $$ = 
COERCION_IMPLICIT; }
Index: src/backend/parser/parse_coerce.c
===================================================================
RCS file: 
/home/hlinnaka/pgcvsrepository/pgsql/src/backend/parser/parse_coerce.c,v
retrieving revision 2.163
diff -c -r2.163 parse_coerce.c
*** src/backend/parser/parse_coerce.c   30 Jul 2008 21:23:17 -0000      2.163
--- src/backend/parser/parse_coerce.c   29 Aug 2008 09:38:51 -0000
***************
*** 1745,1751 ****
                if (ccontext >= castcontext)
                {
                        *funcid = castForm->castfunc;
!                       if (OidIsValid(*funcid))
                                result = COERCION_PATH_FUNC;
                        else
                                result = COERCION_PATH_RELABELTYPE;
--- 1745,1756 ----
                if (ccontext >= castcontext)
                {
                        *funcid = castForm->castfunc;
!                       if (*funcid == IOCOERCE_FUNCOID)
!                       {
!                               result = COERCION_PATH_COERCEVIAIO;
!                               *funcid = InvalidOid;
!                       }
!                       else if (OidIsValid(*funcid))
                                result = COERCION_PATH_FUNC;
                        else
                                result = COERCION_PATH_RELABELTYPE;
Index: src/include/catalog/pg_cast.h
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/include/catalog/pg_cast.h,v
retrieving revision 1.39
diff -c -r1.39 pg_cast.h
*** src/include/catalog/pg_cast.h       27 Mar 2008 03:57:34 -0000      1.39
--- src/include/catalog/pg_cast.h       29 Aug 2008 09:14:15 -0000
***************
*** 56,61 ****
--- 56,63 ----
        COERCION_CODE_EXPLICIT = 'e'    /* explicit cast operation */
  } CoercionCodes;
  
+ #define IOCOERCE_FUNCOID 1
+ 
  
  /* ----------------
   *            compiler constants for pg_cast
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /home/hlinnaka/pgcvsrepository/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.371
diff -c -r1.371 parsenodes.h
*** src/include/nodes/parsenodes.h      7 Aug 2008 01:11:51 -0000       1.371
--- src/include/nodes/parsenodes.h      29 Aug 2008 09:21:08 -0000
***************
*** 1989,1994 ****
--- 1989,1995 ----
        TypeName   *targettype;
        FuncWithArgs *func;
        CoercionContext context;
+       bool            coerceviaio;
  } CreateCastStmt;
  
  /* ----------------------
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@xxxxxxxxxxxxxx)
To make changes to your subscription:
                                www.postgresql.org/mailpref/pgsql-hackers">http://www.postgresql.org/mailpref/pgsql-hackers
<Prev in Thread] Current Thread [Next in Thread>
Privacy Policy