Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit07daff6

Browse files
committed
Fix select_common_type() so that it can select a domain type, if all inputs
to a UNION, CASE, or related construct are of the same domain type. Themain part of this routine smashes domains to their base types, which seemsnecessary because the logic involves TypeCategory() and IsPreferredType(),neither of which work usefully on domains. However, we can add a firstpass that just detects whether all the inputs are exactly the same type,and if so accept that without question (so long as it's not UNKNOWN).Per recent gripe from Dean Rasheed.In passing, remove some tests for InvalidOid, which have clearly been deadcode for quite some time now, because getBaseType() would fail on that input.Also, clarify the manual's not-very-precise description of the existingalgorithm's behavior.
1 parent3f398e4 commit07daff6

File tree

4 files changed

+73
-11
lines changed

4 files changed

+73
-11
lines changed

‎doc/src/sgml/typeconv.sgml

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.52 2007/06/05 21:31:04 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.53 2007/11/26 16:46:50 tgl Exp $ -->
22

33
<chapter Id="typeconv">
44
<title>Type Conversion</title>
@@ -843,11 +843,19 @@ data type.
843843
<title>Type Resolution for <literal>UNION</literal>, <literal>CASE</literal>,
844844
and Related Constructs</title>
845845

846+
<step performance="required">
847+
<para>
848+
If all inputs are of the same type, and it is not <type>unknown</type>,
849+
resolve as that type. Otherwise, replace any domain types in the list with
850+
their underlying base types.
851+
</para>
852+
</step>
853+
846854
<step performance="required">
847855
<para>
848856
If all inputs are of type <type>unknown</type>, resolve as type
849857
<type>text</type> (the preferred type of the string category).
850-
Otherwise,ignorethe <type>unknown</type> inputswhile choosing the result type.
858+
Otherwise, the <type>unknown</type> inputswill be ignored.
851859
</para>
852860
</step>
853861

@@ -860,14 +868,23 @@ If the non-unknown inputs are not all of the same type category, fail.
860868
<step performance="required">
861869
<para>
862870
Choose the first non-unknown input type which is a preferred type in
863-
that category or allows all the non-unknown inputs to be implicitly
864-
converted to it.
871+
that category, if there is one.
872+
</para>
873+
</step>
874+
875+
<step performance="required">
876+
<para>
877+
Otherwise, choose the last non-unknown input type that allows all the
878+
preceding non-unknown inputs to be implicitly converted to it. (There
879+
always is such a type, since at least the first type in the list must
880+
satisfy this condition.)
865881
</para>
866882
</step>
867883

868884
<step performance="required">
869885
<para>
870-
Convert all inputs to the selected type.
886+
Convert all inputs to the selected type. Fail if there is not a
887+
conversion from a given input to the selected type.
871888
</para>
872889
</step>
873890
</procedure>

‎src/backend/parser/parse_coerce.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.158 2007/11/15 21:14:37 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.159 2007/11/26 16:46:50 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -958,7 +958,7 @@ coerce_to_specific_type(ParseState *pstate, Node *node,
958958
*This is used for determining the output type of CASE and UNION
959959
*constructs.
960960
*
961-
* typeids is a nonempty list of type OIDs. Note that earlier items
961+
*'typeids' is a nonempty list of type OIDs. Note that earlier items
962962
* in the list will be preferred if there is doubt.
963963
* 'context' is a phrase to use in the error message if we fail to select
964964
* a usable type.
@@ -971,19 +971,40 @@ select_common_type(List *typeids, const char *context)
971971
ListCell*type_item;
972972

973973
Assert(typeids!=NIL);
974-
ptype=getBaseType(linitial_oid(typeids));
974+
ptype=linitial_oid(typeids);
975+
976+
/*
977+
* If all input types are valid and exactly the same, just pick that type.
978+
* This is the only way that we will resolve the result as being a domain
979+
* type; otherwise domains are smashed to their base types for comparison.
980+
*/
981+
if (ptype!=UNKNOWNOID)
982+
{
983+
for_each_cell(type_item,lnext(list_head(typeids)))
984+
{
985+
Oidntype=lfirst_oid(type_item);
986+
987+
if (ntype!=ptype)
988+
break;
989+
}
990+
if (type_item==NULL)/* got to the end of the list? */
991+
returnptype;
992+
}
993+
994+
/* Nope, so set up for the full algorithm */
995+
ptype=getBaseType(ptype);
975996
pcategory=TypeCategory(ptype);
976997

977998
for_each_cell(type_item,lnext(list_head(typeids)))
978999
{
9791000
Oidntype=getBaseType(lfirst_oid(type_item));
9801001

9811002
/* move on to next one if no new information... */
982-
if ((ntype!=InvalidOid)&& (ntype!=UNKNOWNOID)&&(ntype!=ptype))
1003+
if (ntype!=UNKNOWNOID&&ntype!=ptype)
9831004
{
984-
if ((ptype==InvalidOid)||ptype==UNKNOWNOID)
1005+
if (ptype==UNKNOWNOID)
9851006
{
986-
/* so far, onlynulls so take anything... */
1007+
/* so far, onlyunknowns so take anything... */
9871008
ptype=ntype;
9881009
pcategory=TypeCategory(ptype);
9891010
}

‎src/test/regress/expected/domain.out

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@ from basictest;
6969
|
7070
(3 rows)
7171

72+
-- check that union/case/coalesce type resolution handles domains properly
73+
select coalesce(4::domainint4, 7) is of (int4) as t;
74+
t
75+
---
76+
t
77+
(1 row)
78+
79+
select coalesce(4::domainint4, 7) is of (domainint4) as f;
80+
f
81+
---
82+
f
83+
(1 row)
84+
85+
select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
86+
t
87+
---
88+
t
89+
(1 row)
90+
7291
drop table basictest;
7392
drop domain domainvarchar restrict;
7493
drop domain domainnumeric restrict;

‎src/test/regress/sql/domain.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ select * from basictest;
5858
select testtext|| testvarcharas concat, testnumeric+42as sum
5959
from basictest;
6060

61+
-- check that union/case/coalesce type resolution handles domains properly
62+
select coalesce(4::domainint4,7) is of (int4)as t;
63+
select coalesce(4::domainint4,7) is of (domainint4)as f;
64+
select coalesce(4::domainint4,7::domainint4) is of (domainint4)as t;
65+
6166
droptable basictest;
6267
dropdomain domainvarchar restrict;
6368
dropdomain domainnumeric restrict;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp