Re: Distinct types - Mailing list pgsql-hackers

From Bruce Momjian
Subject Re: Distinct types
Date
Msg-id 200901082048.n08KmPd26951@momjian.us
Whole thread Raw
In response to Distinct types  (Peter Eisentraut <Peter.Eisentraut@Sun.COM>)
List pgsql-hackers
Added to TODO:
Allow the creation of "distinct" types
       * http://archives.postgresql.org/pgsql-hackers/2008-10/msg01647.php 

---------------------------------------------------------------------------

Peter Eisentraut wrote:
> Here is an implementation of distinct types, known from SQL99 and 
> beyond.  They are like domains, except that they don't have defaults or 
> constraints and they do not allow implicit casting to their base type. 
> The latter aspect is what makes them distinct types.  They are useful to 
> create more type-safe database schemas, to prevent using generic types 
> such as text or int for everything and then mixing them in inappropriate 
> ways.  This is something domains are not useful for.  Much of the 
> internals are shared with domains nevertheless.  The difference is 
> really only the casting behavior.
> 
> To create a distinct type, just run
> 
> CREATE TYPE mystring AS text;

> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/commands/typecmds.c ./src/backend/commands/typecmds.c
> *** ../cvs-pgsql/src/backend/commands/typecmds.c    2008-10-21 13:52:23.000000000 +0300
> --- ./src/backend/commands/typecmds.c    2008-10-31 13:50:50.000000000 +0200
> *************** RemoveTypeById(Oid typeOid)
> *** 648,654 ****
>   
>   /*
>    * DefineDomain
> !  *        Registers a new domain.
>    */
>   void
>   DefineDomain(CreateDomainStmt *stmt)
> --- 648,654 ----
>   
>   /*
>    * DefineDomain
> !  *        Registers a new domain or distinct type.
>    */
>   void
>   DefineDomain(CreateDomainStmt *stmt)
> *************** DefineDomain(CreateDomainStmt *stmt)
> *** 721,738 ****
>       basetypeoid = HeapTupleGetOid(typeTup);
>   
>       /*
> !      * Base type must be a plain base type, another domain or an enum. Domains
>        * over pseudotypes would create a security hole.  Domains over composite
>        * types might be made to work in the future, but not today.
>        */
>       typtype = baseType->typtype;
>       if (typtype != TYPTYPE_BASE &&
>           typtype != TYPTYPE_DOMAIN &&
>           typtype != TYPTYPE_ENUM)
> !         ereport(ERROR,
> !                 (errcode(ERRCODE_DATATYPE_MISMATCH),
> !                  errmsg("\"%s\" is not a valid base type for a domain",
> !                         TypeNameToString(stmt->typename))));
>   
>       /* passed by value */
>       byValue = baseType->typbyval;
> --- 721,747 ----
>       basetypeoid = HeapTupleGetOid(typeTup);
>   
>       /*
> !      * Base type must be a plain base type, another domain, distinct type, or an enum. Domains
>        * over pseudotypes would create a security hole.  Domains over composite
>        * types might be made to work in the future, but not today.
>        */
>       typtype = baseType->typtype;
>       if (typtype != TYPTYPE_BASE &&
>           typtype != TYPTYPE_DOMAIN &&
> +         typtype != TYPTYPE_DISTINCT &&
>           typtype != TYPTYPE_ENUM)
> !     {
> !         if (stmt->distinct_type)
> !             ereport(ERROR,
> !                     (errcode(ERRCODE_DATATYPE_MISMATCH),
> !                      errmsg("\"%s\" is not a valid base type for a distinct type",
> !                             TypeNameToString(stmt->typename))));
> !         else
> !             ereport(ERROR,
> !                     (errcode(ERRCODE_DATATYPE_MISMATCH),
> !                      errmsg("\"%s\" is not a valid base type for a domain",
> !                             TypeNameToString(stmt->typename))));
> !     }
>   
>       /* passed by value */
>       byValue = baseType->typbyval;
> *************** DefineDomain(CreateDomainStmt *stmt)
> *** 938,944 ****
>                      InvalidOid,    /* relation oid (n/a here) */
>                      0,            /* relation kind (ditto) */
>                      internalLength,        /* internal size */
> !                    TYPTYPE_DOMAIN,        /* type-type (domain type) */
>                      category,    /* type-category */
>                      false,        /* domain types are never preferred */
>                      delimiter,    /* array element delimiter */
> --- 947,953 ----
>                      InvalidOid,    /* relation oid (n/a here) */
>                      0,            /* relation kind (ditto) */
>                      internalLength,        /* internal size */
> !                    stmt->distinct_type ? TYPTYPE_DISTINCT : TYPTYPE_DOMAIN,        /* type-type (distinct type or
domain)*/
 
>                      category,    /* type-category */
>                      false,        /* domain types are never preferred */
>                      delimiter,    /* array element delimiter */
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/executor/functions.c ./src/backend/executor/functions.c
> *** ../cvs-pgsql/src/backend/executor/functions.c    2008-08-26 01:42:32.000000000 +0300
> --- ./src/backend/executor/functions.c    2008-10-30 14:46:05.000000000 +0200
> *************** check_sql_fn_retval(Oid func_id, Oid ret
> *** 924,929 ****
> --- 924,930 ----
>       fn_typtype = get_typtype(rettype);
>   
>       if (fn_typtype == TYPTYPE_BASE ||
> +         fn_typtype == TYPTYPE_DISTINCT ||
>           fn_typtype == TYPTYPE_DOMAIN ||
>           fn_typtype == TYPTYPE_ENUM ||
>           rettype == VOIDOID)
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/nodes/copyfuncs.c ./src/backend/nodes/copyfuncs.c
> *** ../cvs-pgsql/src/backend/nodes/copyfuncs.c    2008-10-22 14:35:44.000000000 +0300
> --- ./src/backend/nodes/copyfuncs.c    2008-10-30 14:46:05.000000000 +0200
> *************** _copyCreateDomainStmt(CreateDomainStmt *
> *** 2657,2662 ****
> --- 2657,2663 ----
>       COPY_NODE_FIELD(domainname);
>       COPY_NODE_FIELD(typename);
>       COPY_NODE_FIELD(constraints);
> +     COPY_SCALAR_FIELD(distinct_type);
>   
>       return newnode;
>   }
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/nodes/equalfuncs.c ./src/backend/nodes/equalfuncs.c
> *** ../cvs-pgsql/src/backend/nodes/equalfuncs.c    2008-10-22 14:35:44.000000000 +0300
> --- ./src/backend/nodes/equalfuncs.c    2008-10-30 14:46:05.000000000 +0200
> *************** _equalCreateDomainStmt(CreateDomainStmt 
> *** 1342,1347 ****
> --- 1342,1348 ----
>       COMPARE_NODE_FIELD(domainname);
>       COMPARE_NODE_FIELD(typename);
>       COMPARE_NODE_FIELD(constraints);
> +     COMPARE_SCALAR_FIELD(distinct_type);
>   
>       return true;
>   }
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/parser/gram.y ./src/backend/parser/gram.y
> *** ../cvs-pgsql/src/backend/parser/gram.y    2008-10-29 13:37:47.000000000 +0200
> --- ./src/backend/parser/gram.y    2008-10-30 14:46:05.000000000 +0200
> *************** CreateDomainStmt:
> *** 5608,5613 ****
> --- 5608,5623 ----
>                       n->domainname = $3;
>                       n->typename = $5;
>                       n->constraints = $6;
> +                     n->distinct_type = FALSE;
> +                     $$ = (Node *)n;
> +                 }
> +             | CREATE TYPE_P any_name AS Typename
> +                 {
> +                     CreateDomainStmt *n = makeNode(CreateDomainStmt);
> +                     n->domainname = $3;
> +                     n->typename = $5;
> +                     n->constraints = NIL;
> +                     n->distinct_type = TRUE;
>                       $$ = (Node *)n;
>                   }
>           ;
> *************** unreserved_keyword:
> *** 9439,9445 ****
>               | ENABLE_P
>               | ENCODING
>               | ENCRYPTED
> -             | ENUM_P
>               | ESCAPE
>               | EXCLUDING
>               | EXCLUSIVE
> --- 9449,9454 ----
> *************** col_name_keyword:
> *** 9626,9631 ****
> --- 9635,9641 ----
>               | COALESCE
>               | DEC
>               | DECIMAL_P
> +             | ENUM_P
>               | EXISTS
>               | EXTRACT
>               | FLOAT_P
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/parser/keywords.c ./src/backend/parser/keywords.c
> *** ../cvs-pgsql/src/backend/parser/keywords.c    2008-10-28 14:31:25.000000000 +0200
> --- ./src/backend/parser/keywords.c    2008-10-30 14:46:05.000000000 +0200
> *************** const ScanKeyword ScanKeywords[] = {
> *** 157,163 ****
>       {"encoding", ENCODING, UNRESERVED_KEYWORD},
>       {"encrypted", ENCRYPTED, UNRESERVED_KEYWORD},
>       {"end", END_P, RESERVED_KEYWORD},
> !     {"enum", ENUM_P, UNRESERVED_KEYWORD},
>       {"escape", ESCAPE, UNRESERVED_KEYWORD},
>       {"except", EXCEPT, RESERVED_KEYWORD},
>       {"excluding", EXCLUDING, UNRESERVED_KEYWORD},
> --- 157,163 ----
>       {"encoding", ENCODING, UNRESERVED_KEYWORD},
>       {"encrypted", ENCRYPTED, UNRESERVED_KEYWORD},
>       {"end", END_P, RESERVED_KEYWORD},
> !     {"enum", ENUM_P, COL_NAME_KEYWORD},
>       {"escape", ESCAPE, UNRESERVED_KEYWORD},
>       {"except", EXCEPT, RESERVED_KEYWORD},
>       {"excluding", EXCLUDING, UNRESERVED_KEYWORD},
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/parser/parse_coerce.c ./src/backend/parser/parse_coerce.c
> *** ../cvs-pgsql/src/backend/parser/parse_coerce.c    2008-10-27 10:14:16.000000000 +0200
> --- ./src/backend/parser/parse_coerce.c    2008-10-31 13:52:30.000000000 +0200
> *************** find_coercion_pathway(Oid targetTypeId, 
> *** 1867,1881 ****
>       *funcid = InvalidOid;
>   
>       /* Perhaps the types are domains; if so, look at their base types */
> !     if (OidIsValid(sourceTypeId))
>           sourceTypeId = getBaseType(sourceTypeId);
> !     if (OidIsValid(targetTypeId))
>           targetTypeId = getBaseType(targetTypeId);
>   
>       /* Domains are always coercible to and from their base type */
>       if (sourceTypeId == targetTypeId)
>           return COERCION_PATH_RELABELTYPE;
>   
>       /* Look in pg_cast */
>       tuple = SearchSysCache(CASTSOURCETARGET,
>                              ObjectIdGetDatum(sourceTypeId),
> --- 1867,1891 ----
>       *funcid = InvalidOid;
>   
>       /* Perhaps the types are domains; if so, look at their base types */
> !     if (OidIsValid(sourceTypeId) && get_typtype(sourceTypeId) == TYPTYPE_DOMAIN)
>           sourceTypeId = getBaseType(sourceTypeId);
> !     if (OidIsValid(targetTypeId) && get_typtype(targetTypeId) == TYPTYPE_DOMAIN)
>           targetTypeId = getBaseType(targetTypeId);
>   
>       /* Domains are always coercible to and from their base type */
>       if (sourceTypeId == targetTypeId)
>           return COERCION_PATH_RELABELTYPE;
>   
> +     /* Distinct types are castable AS ASSIGNMENT to and from their base types */
> +     if (ccontext >= COERCION_ASSIGNMENT
> +         && ((OidIsValid(sourceTypeId)
> +              && get_typtype(sourceTypeId) == TYPTYPE_DISTINCT
> +              && getDirectBaseType(sourceTypeId) == targetTypeId)
> +             || (OidIsValid(targetTypeId)
> +                 && get_typtype(targetTypeId) == TYPTYPE_DISTINCT
> +                 && getDirectBaseType(targetTypeId) == sourceTypeId)))
> +         return COERCION_PATH_RELABELTYPE;
> + 
>       /* Look in pg_cast */
>       tuple = SearchSysCache(CASTSOURCETARGET,
>                              ObjectIdGetDatum(sourceTypeId),
> *************** find_typmod_coercion_function(Oid typeId
> *** 2021,2026 ****
> --- 2031,2037 ----
>       /* Check for a varlena array type (and not a domain) */
>       if (typeForm->typelem != InvalidOid &&
>           typeForm->typlen == -1 &&
> +         typeForm->typtype != TYPTYPE_DISTINCT &&
>           typeForm->typtype != TYPTYPE_DOMAIN)
>       {
>           /* Yes, switch our attention to the element type */
> Only in ./src/backend/parser: parse_coerce.c.~2.170.~
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/utils/adt/format_type.c ./src/backend/utils/adt/format_type.c
> *** ../cvs-pgsql/src/backend/utils/adt/format_type.c    2008-03-26 00:42:44.000000000 +0200
> --- ./src/backend/utils/adt/format_type.c    2008-10-30 15:30:09.000000000 +0200
> *************** format_type_internal(Oid type_oid, int32
> *** 147,152 ****
> --- 147,153 ----
>   
>       if (array_base_type != InvalidOid &&
>           typeform->typstorage != 'p' &&
> +         typeform->typtype != TYPTYPE_DISTINCT &&
>           typeform->typtype != TYPTYPE_DOMAIN)
>       {
>           /* Switch our attention to the array element type */
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/utils/adt/xml.c ./src/backend/utils/adt/xml.c
> *** ../cvs-pgsql/src/backend/utils/adt/xml.c    2008-10-29 11:32:17.000000000 +0200
> --- ./src/backend/utils/adt/xml.c    2008-10-30 14:46:05.000000000 +0200
> *************** map_sql_typecoll_to_xmlschema_types(List
> *** 2861,2867 ****
>           }
>       }
>   
> !     /* add base types of domains */
>       foreach(cell0, uniquetypes)
>       {
>           Oid            typid = lfirst_oid(cell0);
> --- 2861,2867 ----
>           }
>       }
>   
> !     /* add base types of distinct types and domains */
>       foreach(cell0, uniquetypes)
>       {
>           Oid            typid = lfirst_oid(cell0);
> *************** map_sql_type_to_xmlschema_type(Oid typeo
> *** 3045,3051 ****
>                   break;
>   
>               default:
> !                 if (get_typtype(typeoid) == TYPTYPE_DOMAIN)
>                   {
>                       Oid            base_typeoid;
>                       int32        base_typmod = -1;
> --- 3045,3051 ----
>                   break;
>   
>               default:
> !                 if (get_typtype(typeoid) == TYPTYPE_DISTINCT || get_typtype(typeoid) == TYPTYPE_DOMAIN)
>                   {
>                       Oid            base_typeoid;
>                       int32        base_typmod = -1;
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/utils/cache/lsyscache.c ./src/backend/utils/cache/lsyscache.c
> *** ../cvs-pgsql/src/backend/utils/cache/lsyscache.c    2008-10-02 10:50:16.000000000 +0300
> --- ./src/backend/utils/cache/lsyscache.c    2008-10-31 12:21:48.000000000 +0200
> *************** get_typdefault(Oid typid)
> *** 2032,2038 ****
>   
>   /*
>    * getBaseType
> !  *        If the given type is a domain, return its base type;
>    *        otherwise return the type's own OID.
>    */
>   Oid
> --- 2032,2038 ----
>   
>   /*
>    * getBaseType
> !  *        If the given type is a distinct type or domain, return its base type;
>    *        otherwise return the type's own OID.
>    */
>   Oid
> *************** getBaseType(Oid typid)
> *** 2045,2051 ****
>   
>   /*
>    * getBaseTypeAndTypmod
> !  *        If the given type is a domain, return its base type and typmod;
>    *        otherwise return the type's own OID, and leave *typmod unchanged.
>    *
>    * Note that the "applied typmod" should be -1 for every domain level
> --- 2045,2051 ----
>   
>   /*
>    * getBaseTypeAndTypmod
> !  *        If the given type is a distinct type or domain, return its base type and typmod;
>    *        otherwise return the type's own OID, and leave *typmod unchanged.
>    *
>    * Note that the "applied typmod" should be -1 for every domain level
> *************** getBaseTypeAndTypmod(Oid typid, int32 *t
> *** 2069,2077 ****
>           if (!HeapTupleIsValid(tup))
>               elog(ERROR, "cache lookup failed for type %u", typid);
>           typTup = (Form_pg_type) GETSTRUCT(tup);
> !         if (typTup->typtype != TYPTYPE_DOMAIN)
>           {
> !             /* Not a domain, so done */
>               ReleaseSysCache(tup);
>               break;
>           }
> --- 2069,2077 ----
>           if (!HeapTupleIsValid(tup))
>               elog(ERROR, "cache lookup failed for type %u", typid);
>           typTup = (Form_pg_type) GETSTRUCT(tup);
> !         if (typTup->typtype != TYPTYPE_DISTINCT && typTup->typtype != TYPTYPE_DOMAIN)
>           {
> !             /* Not a distinct type or domain, so done */
>               ReleaseSysCache(tup);
>               break;
>           }
> *************** getBaseTypeAndTypmod(Oid typid, int32 *t
> *** 2087,2092 ****
> --- 2087,2116 ----
>   }
>   
>   /*
> +  * getDirectBaseType
> +  *        If the given type is a distinct type or domain, return its direct base type;
> +  *        otherwise return the type's own OID.
> +  */
> + Oid
> + getDirectBaseType(Oid typid)
> + {
> +     HeapTuple    tup;
> +     Form_pg_type typTup;
> + 
> +     tup = SearchSysCache(TYPEOID,
> +                          ObjectIdGetDatum(typid),
> +                          0, 0, 0);
> +     if (!HeapTupleIsValid(tup))
> +         elog(ERROR, "cache lookup failed for type %u", typid);
> +     typTup = (Form_pg_type) GETSTRUCT(tup);
> +     if (typTup->typtype == TYPTYPE_DISTINCT || typTup->typtype == TYPTYPE_DOMAIN)
> +         typid = typTup->typbasetype;
> +         
> +     ReleaseSysCache(tup);
> +     return typid;
> + }
> + 
> + /*
>    * get_typavgwidth
>    *
>    *      Given a type OID and a typmod value (pass -1 if typmod is unknown),
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/backend/utils/fmgr/funcapi.c ./src/backend/utils/fmgr/funcapi.c
> *** ../cvs-pgsql/src/backend/utils/fmgr/funcapi.c    2008-08-26 01:42:34.000000000 +0300
> --- ./src/backend/utils/fmgr/funcapi.c    2008-10-30 15:28:47.000000000 +0200
> *************** get_type_func_class(Oid typid)
> *** 643,648 ****
> --- 643,649 ----
>           case TYPTYPE_COMPOSITE:
>               return TYPEFUNC_COMPOSITE;
>           case TYPTYPE_BASE:
> +         case TYPTYPE_DISTINCT:
>           case TYPTYPE_DOMAIN:
>           case TYPTYPE_ENUM:
>               return TYPEFUNC_SCALAR;
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/bin/pg_dump/pg_dump.c ./src/bin/pg_dump/pg_dump.c
> *** ../cvs-pgsql/src/bin/pg_dump/pg_dump.c    2008-10-02 10:50:16.000000000 +0300
> --- ./src/bin/pg_dump/pg_dump.c    2008-10-30 17:01:25.000000000 +0200
> *************** static void dumpNamespace(Archive *fout,
> *** 133,138 ****
> --- 133,139 ----
>   static void dumpType(Archive *fout, TypeInfo *tinfo);
>   static void dumpBaseType(Archive *fout, TypeInfo *tinfo);
>   static void dumpEnumType(Archive *fout, TypeInfo *tinfo);
> + static void dumpDistinctType(Archive *fout, TypeInfo *tinfo);
>   static void dumpDomain(Archive *fout, TypeInfo *tinfo);
>   static void dumpCompositeType(Archive *fout, TypeInfo *tinfo);
>   static void dumpShellType(Archive *fout, ShellTypeInfo *stinfo);
> *************** dumpType(Archive *fout, TypeInfo *tinfo)
> *** 5719,5724 ****
> --- 5720,5727 ----
>       /* Dump out in proper style */
>       if (tinfo->typtype == TYPTYPE_BASE)
>           dumpBaseType(fout, tinfo);
> +     else if (tinfo->typtype == TYPTYPE_DISTINCT)
> +         dumpDistinctType(fout, tinfo);
>       else if (tinfo->typtype == TYPTYPE_DOMAIN)
>           dumpDomain(fout, tinfo);
>       else if (tinfo->typtype == TYPTYPE_COMPOSITE)
> *************** dumpBaseType(Archive *fout, TypeInfo *ti
> *** 6174,6179 ****
> --- 6177,6258 ----
>   }
>   
>   /*
> +  * dumpDistinctType
> +  *      writes out to fout the queries to recreate a user-defined distinct type
> +  */
> + static void
> + dumpDistinctType(Archive *fout, TypeInfo *tinfo)
> + {
> +     PQExpBuffer q = createPQExpBuffer();
> +     PQExpBuffer delq = createPQExpBuffer();
> +     PQExpBuffer query = createPQExpBuffer();
> +     PGresult   *res;
> +     int            ntups;
> +     char       *typdefn;
> + 
> +     /* Set proper schema search path so type references list correctly */
> +     selectSourceSchema(tinfo->dobj.namespace->dobj.name);
> + 
> +     /* Fetch type specific details */
> +     appendPQExpBuffer(query, "SELECT pg_catalog.format_type(typbasetype, typtypmod) as typdefn "
> +                       "FROM pg_catalog.pg_type "
> +                       "WHERE oid = '%u'::pg_catalog.oid",
> +                       tinfo->dobj.catId.oid);
> + 
> +     res = PQexec(g_conn, query->data);
> +     check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
> + 
> +     /* Expecting a single result only */
> +     ntups = PQntuples(res);
> +     if (ntups != 1)
> +     {
> +         write_msg(NULL, "query returned %d rows instead of one: %s\n",
> +                   ntups, query->data);
> +         exit_nicely();
> +     }
> + 
> +     typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
> + 
> +     appendPQExpBuffer(q,
> +                       "CREATE TYPE %s AS %s",
> +                       fmtId(tinfo->dobj.name),
> +                       typdefn);
> + 
> +     PQclear(res);
> + 
> +     appendPQExpBuffer(q, ";\n");
> + 
> +     /*
> +      * DROP must be fully qualified in case same name appears in pg_catalog
> +      */
> +     appendPQExpBuffer(delq, "DROP TYPE %s.",
> +                       fmtId(tinfo->dobj.namespace->dobj.name));
> +     appendPQExpBuffer(delq, "%s;\n",
> +                       fmtId(tinfo->dobj.name));
> + 
> +     ArchiveEntry(fout, tinfo->dobj.catId, tinfo->dobj.dumpId,
> +                  tinfo->dobj.name,
> +                  tinfo->dobj.namespace->dobj.name,
> +                  NULL,
> +                  tinfo->rolname, false,
> +                  "TYPE", q->data, delq->data, NULL,
> +                  tinfo->dobj.dependencies, tinfo->dobj.nDeps,
> +                  NULL, NULL);
> + 
> +     /* Dump Type Comments */
> +     resetPQExpBuffer(q);
> + 
> +     appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo->dobj.name));
> +     dumpComment(fout, q->data,
> +                 tinfo->dobj.namespace->dobj.name, tinfo->rolname,
> +                 tinfo->dobj.catId, 0, tinfo->dobj.dumpId);
> + 
> +     destroyPQExpBuffer(q);
> +     destroyPQExpBuffer(delq);
> +     destroyPQExpBuffer(query);
> + }
> + 
> + /*
>    * dumpDomain
>    *      writes out to fout the queries to recreate a user-defined domain
>    */
> Only in ./src/bin/pg_dump: pg_dump.c.~1.502.~
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/include/catalog/pg_type.h ./src/include/catalog/pg_type.h
> *** ../cvs-pgsql/src/include/catalog/pg_type.h    2008-10-15 14:19:43.000000000 +0300
> --- ./src/include/catalog/pg_type.h    2008-10-30 14:46:05.000000000 +0200
> *************** CATALOG(pg_type,1247) BKI_BOOTSTRAP
> *** 60,66 ****
>   
>       /*
>        * typtype is 'b' for a base type, 'c' for a composite type (e.g., a
> !      * table's rowtype), 'd' for a domain type, 'e' for an enum type, or 'p'
>        * for a pseudo-type.  (Use the TYPTYPE macros below.)
>        *
>        * If typtype is 'c', typrelid is the OID of the class' entry in pg_class.
> --- 60,66 ----
>   
>       /*
>        * typtype is 'b' for a base type, 'c' for a composite type (e.g., a
> !      * table's rowtype), 'd' for a domain type, 'D' for a distinct type, 'e' for an enum type, or 'p'
>        * for a pseudo-type.  (Use the TYPTYPE macros below.)
>        *
>        * If typtype is 'c', typrelid is the OID of the class' entry in pg_class.
> *************** DATA(insert OID = 3500 ( anyenum        PGNSP 
> *** 631,636 ****
> --- 631,637 ----
>   #define  TYPTYPE_BASE        'b' /* base type (ordinary scalar type) */
>   #define  TYPTYPE_COMPOSITE    'c' /* composite (e.g., table's rowtype) */
>   #define  TYPTYPE_DOMAIN        'd' /* domain over another type */
> + #define  TYPTYPE_DISTINCT    'D' /* distinct type based on another type */
>   #define  TYPTYPE_ENUM        'e' /* enumerated type */
>   #define  TYPTYPE_PSEUDO        'p' /* pseudo-type */
>   
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/include/nodes/parsenodes.h ./src/include/nodes/parsenodes.h
> *** ../cvs-pgsql/src/include/nodes/parsenodes.h    2008-10-15 14:19:43.000000000 +0300
> --- ./src/include/nodes/parsenodes.h    2008-10-30 14:46:05.000000000 +0200
> *************** typedef struct CreateDomainStmt
> *** 1452,1457 ****
> --- 1452,1458 ----
>       List       *domainname;        /* qualified name (list of Value strings) */
>       TypeName   *typename;        /* the base type */
>       List       *constraints;    /* constraints (list of Constraint nodes) */
> +     bool        distinct_type;    /* create distinct type rather than domain */
>   } CreateDomainStmt;
>   
>   /* ----------------------
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/include/utils/lsyscache.h ./src/include/utils/lsyscache.h
> *** ../cvs-pgsql/src/include/utils/lsyscache.h    2008-10-02 10:50:17.000000000 +0300
> --- ./src/include/utils/lsyscache.h    2008-10-31 12:21:50.000000000 +0200
> *************** extern void getTypeBinaryOutputInfo(Oid 
> *** 123,128 ****
> --- 123,129 ----
>   extern Oid    get_typmodin(Oid typid);
>   extern Oid    getBaseType(Oid typid);
>   extern Oid    getBaseTypeAndTypmod(Oid typid, int32 *typmod);
> + extern Oid    getDirectBaseType(Oid typid);
>   extern int32 get_typavgwidth(Oid typid, int32 typmod);
>   extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
>   extern bool get_attstatsslot(HeapTuple statstuple,
> Only in ./src/include/utils: lsyscache.h.~1.126.~
> diff -x CVS -x TAGS -prc ../cvs-pgsql/src/pl/plpgsql/src/pl_comp.c ./src/pl/plpgsql/src/pl_comp.c
> *** ../cvs-pgsql/src/pl/plpgsql/src/pl_comp.c    2008-10-15 14:19:44.000000000 +0300
> --- ./src/pl/plpgsql/src/pl_comp.c    2008-10-30 15:19:33.000000000 +0200
> *************** build_datatype(HeapTuple typeTup, int32 
> *** 1725,1730 ****
> --- 1725,1731 ----
>       switch (typeStruct->typtype)
>       {
>           case TYPTYPE_BASE:
> +         case TYPTYPE_DISTINCT:
>           case TYPTYPE_DOMAIN:
>           case TYPTYPE_ENUM:
>               typ->ttype = PLPGSQL_TTYPE_SCALAR;

> 
> -- 
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers

--  Bruce Momjian  <bruce@momjian.us>        http://momjian.us EnterpriseDB
http://enterprisedb.com
 + If your life is a hard drive, Christ can be your backup. +


pgsql-hackers by date:

Previous
From: Heikki Linnakangas
Date:
Subject: Re: Hot standby, slot ids and stuff
Next
From: Bruce Momjian
Date:
Subject: Re: [WIP] Reduce alignment requirements on 64-bit systems.