diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2017-10-26 13:47:45 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2017-10-26 13:47:45 -0400 |
commit | 37a795a60b4f4b1def11c615525ec5e0e9449e05 (patch) | |
tree | a5aa9d7e51ef4fd0e353223bd691f7e85018a032 /doc/src | |
parent | 08f1e1f0a47b4b0e87b07b9794698747b279c711 (diff) |
Support domains over composite types.
This is the last major omission in our domains feature: you can now
make a domain over anything that's not a pseudotype.
The major complication from an implementation standpoint is that places
that might be creating tuples of a domain type now need to be prepared
to apply domain_check(). It seems better that unprepared code fail
with an error like "<type> is not composite" than that it silently fail
to apply domain constraints. Therefore, relevant infrastructure like
get_func_result_type() and lookup_rowtype_tupdesc() has been adjusted
to treat domain-over-composite as a distinct case that unprepared code
won't recognize, rather than just transparently treating it the same
as plain composite. This isn't a 100% solution to the possibility of
overlooked domain checks, but it catches most places.
In passing, improve typcache.c's support for domains (it can now cache
the identity of a domain's base type), and rewrite the argument handling
logic in jsonfuncs.c's populate_record[set]_worker to reduce duplicative
per-call lookups.
I believe this is code-complete so far as the core and contrib code go.
The PLs need varying amounts of work, which will be tackled in followup
patches.
Discussion: https://postgr.es/m/4206.1499798337@sss.pgh.pa.us
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/datatype.sgml | 3 | ||||
-rw-r--r-- | doc/src/sgml/rowtypes.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 37 |
3 files changed, 39 insertions, 6 deletions
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index b397e188583..3d46098263d 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -4379,8 +4379,7 @@ SET xmloption TO { DOCUMENT | CONTENT }; underlying type — for example, any operator or function that can be applied to the underlying type will work on the domain type. The underlying type can be any built-in or user-defined base type, - enum type, array or range type, or another domain. (Currently, domains - over composite types are not implemented.) + enum type, array type, composite type, range type, or another domain. </para> <para> diff --git a/doc/src/sgml/rowtypes.sgml b/doc/src/sgml/rowtypes.sgml index 7e436a46065..f80d44bc75c 100644 --- a/doc/src/sgml/rowtypes.sgml +++ b/doc/src/sgml/rowtypes.sgml @@ -84,8 +84,9 @@ CREATE TABLE inventory_item ( restriction of the current implementation: since no constraints are associated with a composite type, the constraints shown in the table definition <emphasis>do not apply</emphasis> to values of the composite type - outside the table. (A partial workaround is to use domain - types as members of composite types.) + outside the table. (To work around this, create a domain over the composite + type, and apply the desired constraints as <literal>CHECK</literal> + constraints of the domain.) </para> </sect2> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index d9fccaa17c6..9bdb72cd989 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -353,6 +353,31 @@ CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$ $$ LANGUAGE SQL; </programlisting> </para> + + <para> + A <acronym>SQL</acronym> function must return exactly its declared + result type. This may require inserting an explicit cast. + For example, suppose we wanted the + previous <function>add_em</function> function to return + type <type>float8</type> instead. This won't work: + +<programlisting> +CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$ + SELECT $1 + $2; +$$ LANGUAGE SQL; +</programlisting> + + even though in other contexts <productname>PostgreSQL</productname> + would be willing to insert an implicit cast to + convert <type>integer</type> to <type>float8</type>. + We need to write it as + +<programlisting> +CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$ + SELECT ($1 + $2)::float8; +$$ LANGUAGE SQL; +</programlisting> + </para> </sect2> <sect2 id="xfunc-sql-composite-functions"> @@ -452,13 +477,16 @@ $$ LANGUAGE SQL; </listitem> <listitem> <para> - You must typecast the expressions to match the - definition of the composite type, or you will get errors like this: + We must ensure each expression's type matches the corresponding + column of the composite type, inserting a cast if necessary. + Otherwise we'll get errors like this: <screen> <computeroutput> ERROR: function declared to return emp returns varchar instead of text at column 1 </computeroutput> </screen> + As with the base-type case, the function will not insert any casts + automatically. </para> </listitem> </itemizedlist> @@ -478,6 +506,11 @@ $$ LANGUAGE SQL; in this situation, but it is a handy alternative in some cases — for example, if we need to compute the result by calling another function that returns the desired composite value. + Another example is that if we are trying to write a function that + returns a domain over composite, rather than a plain composite type, + it is always necessary to write it as returning a single column, + since there is no other way to produce a value that is exactly of + the domain type. </para> <para> |