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

Commit7d6af50

Browse files
committed
Make algorithm for resolving UNKNOWN function/operator inputs be
insensitive to the order of arguments. Per pghackers discussion 12/10/00.
1 parentff783fb commit7d6af50

File tree

2 files changed

+229
-151
lines changed

2 files changed

+229
-151
lines changed

‎src/backend/parser/parse_func.c

Lines changed: 113 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.94 2000/11/1622:30:28 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.95 2000/12/15 19:22:03 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -759,14 +759,15 @@ func_select_candidate(int nargs,
759759
CandidateListcurrent_candidate;
760760
CandidateListlast_candidate;
761761
Oid*current_typeids;
762+
Oidcurrent_type;
762763
inti;
763764
intncandidates;
764765
intnbestMatch,
765766
nmatch;
766-
CATEGORYslot_category,
767+
CATEGORYslot_category[FUNC_MAX_ARGS],
767768
current_category;
768-
Oidslot_type,
769-
current_type;
769+
boolslot_has_preferred_type[FUNC_MAX_ARGS];
770+
boolresolved_unknowns;
770771

771772
/*
772773
* Run through all candidates and keep those with the most matches on
@@ -911,98 +912,133 @@ func_select_candidate(int nargs,
911912
* Still too many candidates? Try assigning types for the unknown
912913
* columns.
913914
*
914-
* We do this by examining each unknown argument position to see if all
915-
* the candidates agree on the type category of that slot.If so, and
916-
* if some candidates accept the preferred type in that category,
917-
* eliminate the candidates with other input types. If we are down to
918-
* one candidate at the end, we win.
915+
* We do this by examining each unknown argument position to see if we
916+
* can determine a "type category" for it. If any candidate has an
917+
* input datatype of STRING category, use STRING category (this bias
918+
* towards STRING is appropriate since unknown-type literals look like
919+
* strings). Otherwise, if all the candidates agree on the type
920+
* category of this argument position, use that category. Otherwise,
921+
* fail because we cannot determine a category.
919922
*
920-
* XXX It's kinda bogus to do this left-to-right, isn't it? If we
921-
* eliminate some candidates because they are non-preferred at the
922-
* first slot, we won't notice that they didn't have the same type
923-
* category for a later slot.
924-
* XXX Hmm. How else would you do this? These candidates are here because
925-
* they all have the same number of matches on arguments with explicit
926-
* types, so from here on left-to-right resolution is as good as any.
927-
* Need a counterexample to see otherwise...
923+
* If we are able to determine a type category, also notice whether
924+
* any of the candidates takes a preferred datatype within the category.
925+
*
926+
* Having completed this examination, remove candidates that accept
927+
* the wrong category at any unknown position. Also, if at least one
928+
* candidate accepted a preferred type at a position, remove candidates
929+
* that accept non-preferred types.
930+
*
931+
* If we are down to one candidate at the end, we win.
928932
*/
933+
resolved_unknowns= false;
929934
for (i=0;i<nargs;i++)
930935
{
931-
if (input_typeids[i]==UNKNOWNOID)
936+
boolhave_conflict;
937+
938+
if (input_typeids[i]!=UNKNOWNOID)
939+
continue;
940+
resolved_unknowns= true;/* assume we can do it */
941+
slot_category[i]=INVALID_TYPE;
942+
slot_has_preferred_type[i]= false;
943+
have_conflict= false;
944+
for (current_candidate=candidates;
945+
current_candidate!=NULL;
946+
current_candidate=current_candidate->next)
932947
{
933-
slot_category=INVALID_TYPE;
934-
slot_type=InvalidOid;
935-
last_candidate=NULL;
936-
for (current_candidate=candidates;
937-
current_candidate!=NULL;
938-
current_candidate=current_candidate->next)
948+
current_typeids=current_candidate->args;
949+
current_type=current_typeids[i];
950+
current_category=TypeCategory(current_type);
951+
if (slot_category[i]==INVALID_TYPE)
939952
{
940-
current_typeids=current_candidate->args;
941-
current_type=current_typeids[i];
942-
current_category=TypeCategory(current_type);
943-
if (slot_category==INVALID_TYPE)
953+
/* first candidate */
954+
slot_category[i]=current_category;
955+
slot_has_preferred_type[i]=
956+
IsPreferredType(current_category,current_type);
957+
}
958+
elseif (current_category==slot_category[i])
959+
{
960+
/* more candidates in same category */
961+
slot_has_preferred_type[i] |=
962+
IsPreferredType(current_category,current_type);
963+
}
964+
else
965+
{
966+
/* category conflict! */
967+
if (current_category==STRING_TYPE)
944968
{
945-
slot_category=current_category;
946-
slot_type=current_type;
947-
last_candidate=current_candidate;
969+
/* STRING always wins if available */
970+
slot_category[i]=current_category;
971+
slot_has_preferred_type[i]=
972+
IsPreferredType(current_category,current_type);
948973
}
949-
elseif (current_category!=slot_category)
974+
else
950975
{
951-
/* started out as unknown type, so give preference to string type, if available */
952-
if (current_category==STRING_TYPE)
953-
{
954-
slot_category=current_category;
955-
slot_type=current_type;
956-
/* forget all previous candidates */
957-
candidates=current_candidate;
958-
last_candidate=current_candidate;
959-
}
960-
elseif (slot_category==STRING_TYPE)
961-
{
962-
/* forget this candidate */
963-
if (last_candidate)
964-
last_candidate->next=current_candidate->next;
965-
else
966-
candidates=current_candidate->next;
967-
}
976+
/* Remember conflict, but keep going (might find STRING) */
977+
have_conflict= true;
968978
}
969-
elseif (current_type!=slot_type)
979+
}
980+
}
981+
if (have_conflict&&slot_category[i]!=STRING_TYPE)
982+
{
983+
/* Failed to resolve category conflict at this position */
984+
resolved_unknowns= false;
985+
break;
986+
}
987+
}
988+
989+
if (resolved_unknowns)
990+
{
991+
/* Strip non-matching candidates */
992+
ncandidates=0;
993+
last_candidate=NULL;
994+
for (current_candidate=candidates;
995+
current_candidate!=NULL;
996+
current_candidate=current_candidate->next)
997+
{
998+
boolkeepit= true;
999+
1000+
current_typeids=current_candidate->args;
1001+
for (i=0;i<nargs;i++)
1002+
{
1003+
if (input_typeids[i]!=UNKNOWNOID)
1004+
continue;
1005+
current_type=current_typeids[i];
1006+
current_category=TypeCategory(current_type);
1007+
if (current_category!=slot_category[i])
9701008
{
971-
if (IsPreferredType(slot_category,current_type))
972-
{
973-
slot_type=current_type;
974-
/* forget all previous candidates */
975-
candidates=current_candidate;
976-
last_candidate=current_candidate;
977-
}
978-
elseif (IsPreferredType(slot_category,slot_type))
979-
{
980-
/* forget this candidate */
981-
if (last_candidate)
982-
last_candidate->next=current_candidate->next;
983-
else
984-
candidates=current_candidate->next;
985-
}
986-
else
987-
last_candidate=current_candidate;
1009+
keepit= false;
1010+
break;
9881011
}
989-
else
1012+
if (slot_has_preferred_type[i]&&
1013+
!IsPreferredType(current_category,current_type))
9901014
{
991-
/* keep this candidate */
992-
last_candidate=current_candidate;
1015+
keepit= false;
1016+
break;
9931017
}
9941018
}
995-
if (last_candidate)/* terminate rebuilt list */
996-
last_candidate->next=NULL;
1019+
if (keepit)
1020+
{
1021+
/* keep this candidate */
1022+
last_candidate=current_candidate;
1023+
ncandidates++;
1024+
}
1025+
else
1026+
{
1027+
/* forget this candidate */
1028+
if (last_candidate)
1029+
last_candidate->next=current_candidate->next;
1030+
else
1031+
candidates=current_candidate->next;
1032+
}
9971033
}
1034+
if (last_candidate)/* terminate rebuilt list */
1035+
last_candidate->next=NULL;
9981036
}
9991037

1000-
if (candidates==NULL)
1001-
returnNULL;/* no remaining candidates */
1002-
if (candidates->next!=NULL)
1003-
returnNULL;/* more than one remaining candidate */
1038+
if (ncandidates==1)
1039+
returncandidates->args;
10041040

1005-
returncandidates->args;
1041+
returnNULL;/* failed to determine a unique candidate */
10061042
}/* func_select_candidate() */
10071043

10081044

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp