Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0e99be1

Browse files
committed
Remove useless argtype_inherit() code, and make consequent simplifications.
As I pointed out a few days ago, this code has failed to do anything useful for some time ... and if we did want to revive the capability to select functions by nearness of inheritance ancestry, this is the wrong place and way to do it anyway. The knowledge would need to go into func_select_candidate() instead. Perhaps someday someone will be motivated to do that, but I am not today.
1 parent ac8998f commit 0e99be1

File tree

1 file changed

+45
-251
lines changed

1 file changed

+45
-251
lines changed

src/backend/parser/parse_func.c

Lines changed: 45 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.178 2005/04/14 20:03:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.179 2005/04/23 22:09:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -34,10 +34,6 @@
3434

3535
static Node *ParseComplexProjection(ParseState *pstate, char *funcname,
3636
Node *first_arg);
37-
static Oid **argtype_inherit(int nargs, Oid *argtypes);
38-
39-
static int find_inheritors(Oid relid, Oid **supervec);
40-
static Oid **gen_cross_product(InhPaths *arginh, int nargs);
4137
static void unknown_attribute(ParseState *pstate, Node *relref, char *attname);
4238

4339

@@ -754,63 +750,34 @@ func_get_detail(List *funcname,
754750
*/
755751
if (raw_candidates != NULL)
756752
{
757-
Oid **input_typeid_vector = NULL;
758-
Oid *current_input_typeids;
753+
FuncCandidateList current_candidates;
754+
int ncandidates;
755+
756+
ncandidates = func_match_argtypes(nargs,
757+
argtypes,
758+
raw_candidates,
759+
&current_candidates);
760+
761+
/* one match only? then run with it... */
762+
if (ncandidates == 1)
763+
best_candidate = current_candidates;
759764

760765
/*
761-
* First we will search with the given argtypes, then with
762-
* variants based on replacing complex types with their
763-
* inheritance ancestors. Stop as soon as any match is found.
766+
* multiple candidates? then better decide or throw an error...
764767
*/
765-
current_input_typeids = argtypes;
766-
767-
do
768+
else if (ncandidates > 1)
768769
{
769-
FuncCandidateList current_candidates;
770-
int ncandidates;
771-
772-
ncandidates = func_match_argtypes(nargs,
773-
current_input_typeids,
774-
raw_candidates,
775-
&current_candidates);
776-
777-
/* one match only? then run with it... */
778-
if (ncandidates == 1)
779-
{
780-
best_candidate = current_candidates;
781-
break;
782-
}
770+
best_candidate = func_select_candidate(nargs,
771+
argtypes,
772+
current_candidates);
783773

784774
/*
785-
* multiple candidates? then better decide or throw an
786-
* error...
775+
* If we were able to choose a best candidate, we're
776+
* done. Otherwise, ambiguous function call.
787777
*/
788-
if (ncandidates > 1)
789-
{
790-
best_candidate = func_select_candidate(nargs,
791-
current_input_typeids,
792-
current_candidates);
793-
794-
/*
795-
* If we were able to choose a best candidate, we're
796-
* done. Otherwise, ambiguous function call.
797-
*/
798-
if (best_candidate)
799-
break;
778+
if (!best_candidate)
800779
return FUNCDETAIL_MULTIPLE;
801-
}
802-
803-
/*
804-
* No match here, so try the next inherited type vector.
805-
* First time through, we need to compute the list of
806-
* vectors.
807-
*/
808-
if (input_typeid_vector == NULL)
809-
input_typeid_vector = argtype_inherit(nargs, argtypes);
810-
811-
current_input_typeids = *input_typeid_vector++;
812780
}
813-
while (current_input_typeids != NULL);
814781
}
815782
}
816783

@@ -840,81 +807,27 @@ func_get_detail(List *funcname,
840807
return FUNCDETAIL_NOTFOUND;
841808
}
842809

843-
/*
844-
* argtype_inherit() -- Construct an argtype vector reflecting the
845-
* inheritance properties of the supplied argv.
846-
*
847-
* This function is used to handle resolution of function calls when
848-
* there is no match to the given argument types, but there might be
849-
* matches based on considering complex types as members of their
850-
* superclass types (parent classes).
851-
*
852-
* It takes an array of input type ids. For each type id in the array
853-
* that's a complex type (a class), it walks up the inheritance tree,
854-
* finding all superclasses of that type. A vector of new Oid type
855-
* arrays is returned to the caller, listing possible alternative
856-
* interpretations of the input typeids as members of their superclasses
857-
* rather than the actually given argument types. The vector is
858-
* terminated by a NULL pointer.
859-
*
860-
* The order of this vector is as follows: all superclasses of the
861-
* rightmost complex class are explored first. The exploration
862-
* continues from right to left. This policy means that we favor
863-
* keeping the leftmost argument type as low in the inheritance tree
864-
* as possible. This is intentional; it is exactly what we need to
865-
* do for method dispatch.
866-
*
867-
* The vector does not include the case where no complex classes have
868-
* been promoted, since that was already tried before this routine
869-
* got called.
870-
*/
871-
static Oid **
872-
argtype_inherit(int nargs, Oid *argtypes)
873-
{
874-
Oid **result;
875-
Oid relid;
876-
int i;
877-
InhPaths *arginh;
878-
879-
/* Set up the vector of superclass information */
880-
arginh = (InhPaths *) palloc(nargs * sizeof(InhPaths));
881-
882-
for (i = 0; i < nargs; i++)
883-
{
884-
arginh[i].self = argtypes[i];
885-
if ((relid = typeidTypeRelid(argtypes[i])) != InvalidOid)
886-
arginh[i].nsupers = find_inheritors(relid, &(arginh[i].supervec));
887-
else
888-
{
889-
arginh[i].nsupers = 0;
890-
arginh[i].supervec = NULL;
891-
}
892-
}
893-
894-
/* Compute an ordered cross-product of the classes involved */
895-
result = gen_cross_product(arginh, nargs);
896-
897-
pfree(arginh);
898-
899-
return result;
900-
}
901810

902811
/*
903-
* Look up the parent superclass(es) of the given relation.
904-
*
905-
* *supervec is set to an array of the type OIDs (not the relation OIDs)
906-
* of the parents, with nearest ancestors listed first. It's set to NULL
907-
* if there are no parents. The return value is the number of parents.
812+
* Given two type OIDs, determine whether the first is a complex type
813+
* (class type) that inherits from the second.
908814
*/
909-
static int
910-
find_inheritors(Oid relid, Oid **supervec)
815+
bool
816+
typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
911817
{
818+
bool result = false;
819+
Oid relid;
912820
Relation inhrel;
913-
int nvisited;
914821
List *visited,
915822
*queue;
916823
ListCell *queue_item;
917824

825+
if (!ISCOMPLEX(subclassTypeId) || !ISCOMPLEX(superclassTypeId))
826+
return false;
827+
relid = typeidTypeRelid(subclassTypeId);
828+
if (relid == InvalidOid)
829+
return false;
830+
918831
/*
919832
* Begin the search at the relation itself, so add relid to the queue.
920833
*/
@@ -960,149 +873,30 @@ find_inheritors(Oid relid, Oid **supervec)
960873
while ((inhtup = heap_getnext(inhscan, ForwardScanDirection)) != NULL)
961874
{
962875
Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
876+
Oid inhparent = inh->inhparent;
877+
878+
/* If this is the target superclass, we're done */
879+
if (get_rel_type_id(inhparent) == superclassTypeId)
880+
{
881+
result = true;
882+
break;
883+
}
963884

964-
queue = lappend_oid(queue, inh->inhparent);
885+
/* Else add to queue */
886+
queue = lappend_oid(queue, inhparent);
965887
}
966888

967889
heap_endscan(inhscan);
890+
891+
if (result)
892+
break;
968893
}
969894

970895
heap_close(inhrel, AccessShareLock);
971896

972-
nvisited = list_length(visited);
973-
if (nvisited > 0)
974-
{
975-
Oid *relidvec;
976-
ListCell *l;
977-
978-
relidvec = (Oid *) palloc(nvisited * sizeof(*relidvec));
979-
*supervec = relidvec;
980-
981-
foreach(l, visited)
982-
{
983-
/* return the type id, rather than the relation id */
984-
*relidvec++ = get_rel_type_id(lfirst_oid(l));
985-
}
986-
}
987-
else
988-
*supervec = NULL;
989-
990897
list_free(visited);
991898
list_free(queue);
992899

993-
return nvisited;
994-
}
995-
996-
/*
997-
* Generate the ordered list of substitute argtype vectors to try.
998-
*
999-
* See comments for argtype_inherit.
1000-
*/
1001-
static Oid **
1002-
gen_cross_product(InhPaths *arginh, int nargs)
1003-
{
1004-
int nanswers;
1005-
Oid **result;
1006-
Oid *oneres;
1007-
int i,
1008-
j;
1009-
int *cur;
1010-
1011-
/*
1012-
* At each position we want to try the original datatype, plus each
1013-
* supertype. So the number of possible combinations is this:
1014-
*/
1015-
nanswers = 1;
1016-
for (i = 0; i < nargs; i++)
1017-
nanswers *= (arginh[i].nsupers + 1);
1018-
1019-
/*
1020-
* We also need an extra slot for the terminating NULL in the result
1021-
* array, but that cancels out with the fact that we don't want to
1022-
* generate the zero-changes case. So we need exactly nanswers slots.
1023-
*/
1024-
result = (Oid **) palloc(sizeof(Oid *) * nanswers);
1025-
j = 0;
1026-
1027-
/*
1028-
* Compute the cross product from right to left. When cur[i] == 0,
1029-
* generate the original input type at position i. When cur[i] == k
1030-
* for k > 0, generate its k'th supertype.
1031-
*/
1032-
cur = (int *) palloc0(nargs * sizeof(int));
1033-
1034-
for (;;)
1035-
{
1036-
/*
1037-
* Find a column we can increment. All the columns after it get
1038-
* reset to zero. (Essentially, we're adding one to the multi-
1039-
* digit number represented by cur[].)
1040-
*/
1041-
for (i = nargs - 1; i >= 0 && cur[i] >= arginh[i].nsupers; i--)
1042-
cur[i] = 0;
1043-
1044-
/* if none, we're done */
1045-
if (i < 0)
1046-
break;
1047-
1048-
/* increment this column */
1049-
cur[i] += 1;
1050-
1051-
/* Generate the proper output type-OID vector */
1052-
oneres = (Oid *) palloc(nargs * sizeof(Oid));
1053-
1054-
for (i = 0; i < nargs; i++)
1055-
{
1056-
if (cur[i] == 0)
1057-
oneres[i] = arginh[i].self;
1058-
else
1059-
oneres[i] = arginh[i].supervec[cur[i] - 1];
1060-
}
1061-
1062-
result[j++] = oneres;
1063-
}
1064-
1065-
/* terminate result vector with NULL pointer */
1066-
result[j++] = NULL;
1067-
1068-
Assert(j == nanswers);
1069-
1070-
pfree(cur);
1071-
1072-
return result;
1073-
}
1074-
1075-
1076-
/*
1077-
* Given two type OIDs, determine whether the first is a complex type
1078-
* (class type) that inherits from the second.
1079-
*/
1080-
bool
1081-
typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
1082-
{
1083-
Oid relid;
1084-
Oid *supervec;
1085-
int nsupers,
1086-
i;
1087-
bool result;
1088-
1089-
if (!ISCOMPLEX(subclassTypeId) || !ISCOMPLEX(superclassTypeId))
1090-
return false;
1091-
relid = typeidTypeRelid(subclassTypeId);
1092-
if (relid == InvalidOid)
1093-
return false;
1094-
nsupers = find_inheritors(relid, &supervec);
1095-
result = false;
1096-
for (i = 0; i < nsupers; i++)
1097-
{
1098-
if (supervec[i] == superclassTypeId)
1099-
{
1100-
result = true;
1101-
break;
1102-
}
1103-
}
1104-
if (supervec)
1105-
pfree(supervec);
1106900
return result;
1107901
}
1108902

0 commit comments

Comments
 (0)