Index: doc/src/sgml/typeconv.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/typeconv.sgml,v
retrieving revision 1.52
diff -c -r1.52 typeconv.sgml
*** doc/src/sgml/typeconv.sgml 5 Jun 2007 21:31:04 -0000 1.52
--- doc/src/sgml/typeconv.sgml 25 Nov 2007 01:33:03 -0000
***************
*** 845,853 ****
If all inputs are of type unknown, resolve as type
text (the preferred type of the string category).
! Otherwise, ignore the unknown inputs while choosing the result type.
--- 845,861 ----
+ If all inputs are of the same type, and it is not unknown,
+ resolve as that type. Otherwise, replace any domain types in the list with
+ their underlying base types.
+
+
+
+
+
If all inputs are of type unknown, resolve as type
text (the preferred type of the string category).
! Otherwise, the unknown inputs will be ignored.
***************
*** 860,873 ****
Choose the first non-unknown input type which is a preferred type in
! that category or allows all the non-unknown inputs to be implicitly
! converted to it.
! Convert all inputs to the selected type.
--- 868,890 ----
Choose the first non-unknown input type which is a preferred type in
! that category, if there is one.
!
!
!
!
!
! Otherwise, choose the last non-unknown input type that allows all the
! preceding non-unknown inputs to be implicitly converted to it. (There
! always is such a type, since at least the first type in the list must
! satisfy this condition.)
! Convert all inputs to the selected type. Fail if there is not a
! conversion from a given input to the selected type.
Index: src/backend/parser/parse_coerce.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v
retrieving revision 2.158
diff -c -r2.158 parse_coerce.c
*** src/backend/parser/parse_coerce.c 15 Nov 2007 21:14:37 -0000 2.158
--- src/backend/parser/parse_coerce.c 25 Nov 2007 01:33:04 -0000
***************
*** 958,964 ****
* This is used for determining the output type of CASE and UNION
* constructs.
*
! * typeids is a nonempty list of type OIDs. Note that earlier items
* in the list will be preferred if there is doubt.
* 'context' is a phrase to use in the error message if we fail to select
* a usable type.
--- 958,964 ----
* This is used for determining the output type of CASE and UNION
* constructs.
*
! * 'typeids' is a nonempty list of type OIDs. Note that earlier items
* in the list will be preferred if there is doubt.
* 'context' is a phrase to use in the error message if we fail to select
* a usable type.
***************
*** 971,977 ****
ListCell *type_item;
Assert(typeids != NIL);
! ptype = getBaseType(linitial_oid(typeids));
pcategory = TypeCategory(ptype);
for_each_cell(type_item, lnext(list_head(typeids)))
--- 971,998 ----
ListCell *type_item;
Assert(typeids != NIL);
! ptype = linitial_oid(typeids);
!
! /*
! * If all input types are valid and exactly the same, just pick that type.
! * This is the only way that we will resolve the result as being a domain
! * type; otherwise domains are smashed to their base types for comparison.
! */
! if (ptype != UNKNOWNOID)
! {
! for_each_cell(type_item, lnext(list_head(typeids)))
! {
! Oid ntype = lfirst_oid(type_item);
!
! if (ntype != ptype)
! break;
! }
! if (type_item == NULL) /* got to the end of the list? */
! return ptype;
! }
!
! /* Nope, so set up for the full algorithm */
! ptype = getBaseType(ptype);
pcategory = TypeCategory(ptype);
for_each_cell(type_item, lnext(list_head(typeids)))
***************
*** 979,989 ****
Oid ntype = getBaseType(lfirst_oid(type_item));
/* move on to next one if no new information... */
! if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
{
! if ((ptype == InvalidOid) || ptype == UNKNOWNOID)
{
! /* so far, only nulls so take anything... */
ptype = ntype;
pcategory = TypeCategory(ptype);
}
--- 1000,1010 ----
Oid ntype = getBaseType(lfirst_oid(type_item));
/* move on to next one if no new information... */
! if (ntype != UNKNOWNOID && ntype != ptype)
{
! if (ptype == UNKNOWNOID)
{
! /* so far, only unknowns so take anything... */
ptype = ntype;
pcategory = TypeCategory(ptype);
}
Index: src/test/regress/expected/domain.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/domain.out,v
retrieving revision 1.42
diff -c -r1.42 domain.out
*** src/test/regress/expected/domain.out 29 Oct 2007 19:40:40 -0000 1.42
--- src/test/regress/expected/domain.out 25 Nov 2007 01:33:04 -0000
***************
*** 69,74 ****
--- 69,93 ----
|
(3 rows)
+ -- check that union/case/coalesce type resolution handles domains properly
+ select coalesce(4::domainint4, 7) is of (int4) as t;
+ t
+ ---
+ t
+ (1 row)
+
+ select coalesce(4::domainint4, 7) is of (domainint4) as f;
+ f
+ ---
+ f
+ (1 row)
+
+ select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
+ t
+ ---
+ t
+ (1 row)
+
drop table basictest;
drop domain domainvarchar restrict;
drop domain domainnumeric restrict;
Index: src/test/regress/sql/domain.sql
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/sql/domain.sql,v
retrieving revision 1.25
diff -c -r1.25 domain.sql
*** src/test/regress/sql/domain.sql 29 Oct 2007 19:40:40 -0000 1.25
--- src/test/regress/sql/domain.sql 25 Nov 2007 01:33:04 -0000
***************
*** 58,63 ****
--- 58,68 ----
select testtext || testvarchar as concat, testnumeric + 42 as sum
from basictest;
+ -- check that union/case/coalesce type resolution handles domains properly
+ select coalesce(4::domainint4, 7) is of (int4) as t;
+ select coalesce(4::domainint4, 7) is of (domainint4) as f;
+ select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
+
drop table basictest;
drop domain domainvarchar restrict;
drop domain domainnumeric restrict;