88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.150 2003/06/24 23:14:45 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.151 2003/06/25 20:07:39 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -925,23 +925,29 @@ func_get_detail(List *funcname,
925925 *argtype_inherit() -- Construct an argtype vector reflecting the
926926 * inheritance properties of the supplied argv.
927927 *
928- *This function is used to disambiguate among functions with the
929- *same name but different signatures. It takes an array of input
930- *type ids. For each type id in the array that's a complex type
931- *(a class), it walks up the inheritance tree, finding all
932- *superclasses of that type.A vector of new Oid type arrays
933- *is returned to the caller, reflecting the structure of the
934- *inheritance tree above the supplied arguments.
928+ *This function is used to handle resolution of function calls when
929+ *there is no match to the given argument types, but there might be
930+ *matches based on considering complex types as members of their
931+ *superclass types (parent classes).
932+ *
933+ *It takes an array of input type ids. For each type id in the array
934+ *that's a complex type (a class), it walks up the inheritance tree,
935+ *finding all superclasses of that type. A vector of new Oid type
936+ *arrays is returned to the caller, listing possible alternative
937+ *interpretations of the input typeids as members of their superclasses
938+ *rather than the actually given argument types. The vector is
939+ *terminated by a NULL pointer.
935940 *
936941 *The order of this vector is as follows: all superclasses of the
937942 *rightmost complex class are explored first. The exploration
938943 *continues from right to left. This policy means that we favor
939944 *keeping the leftmost argument type as low in the inheritance tree
940945 *as possible. This is intentional; it is exactly what we need to
941- *do for method dispatch. The last type array we return is all
942- *zeroes. This will match any functions for which return types are
943- *not defined. There are lots of these (mostly builtins) in the
944- *catalogs.
946+ *do for method dispatch.
947+ *
948+ *The vector does not include the case where no complex classes have
949+ *been promoted, since that was already tried before this routine
950+ *got called.
945951 */
946952static Oid * *
947953argtype_inherit (int nargs ,Oid * argtypes )
@@ -950,22 +956,13 @@ argtype_inherit(int nargs, Oid *argtypes)
950956int i ;
951957InhPaths arginh [FUNC_MAX_ARGS ];
952958
953- for (i = 0 ;i < FUNC_MAX_ARGS ;i ++ )
959+ for (i = 0 ;i < nargs ;i ++ )
954960{
955- if (i < nargs )
956- {
957- arginh [i ].self = argtypes [i ];
958- if ((relid = typeidTypeRelid (argtypes [i ]))!= InvalidOid )
959- arginh [i ].nsupers = find_inheritors (relid ,& (arginh [i ].supervec ));
960- else
961- {
962- arginh [i ].nsupers = 0 ;
963- arginh [i ].supervec = (Oid * )NULL ;
964- }
965- }
961+ arginh [i ].self = argtypes [i ];
962+ if ((relid = typeidTypeRelid (argtypes [i ]))!= InvalidOid )
963+ arginh [i ].nsupers = find_inheritors (relid ,& (arginh [i ].supervec ));
966964else
967965{
968- arginh [i ].self = InvalidOid ;
969966arginh [i ].nsupers = 0 ;
970967arginh [i ].supervec = (Oid * )NULL ;
971968}
@@ -975,6 +972,13 @@ argtype_inherit(int nargs, Oid *argtypes)
975972return gen_cross_product (arginh ,nargs );
976973}
977974
975+ /*
976+ * Look up the parent superclass(es) of the given relation.
977+ *
978+ * *supervec is set to an array of the type OIDs (not the relation OIDs)
979+ * of the parents, with nearest ancestors listed first. It's set to NULL
980+ * if there are no parents. The return value is the number of parents.
981+ */
978982static int
979983find_inheritors (Oid relid ,Oid * * supervec )
980984{
@@ -1068,58 +1072,81 @@ find_inheritors(Oid relid, Oid **supervec)
10681072return nvisited ;
10691073}
10701074
1075+ /*
1076+ * Generate the ordered list of substitute argtype vectors to try.
1077+ *
1078+ * See comments for argtype_inherit.
1079+ */
10711080static Oid * *
10721081gen_cross_product (InhPaths * arginh ,int nargs )
10731082{
10741083int nanswers ;
1075- Oid * * result ,
1076- * * iter ;
1084+ Oid * * result ;
10771085Oid * oneres ;
10781086int i ,
10791087j ;
10801088int cur [FUNC_MAX_ARGS ];
10811089
1090+ /*
1091+ * At each position we want to try the original datatype, plus each
1092+ * supertype. So the number of possible combinations is this:
1093+ */
10821094nanswers = 1 ;
10831095for (i = 0 ;i < nargs ;i ++ )
1084- {
1085- nanswers *= (arginh [i ].nsupers + 2 );
1086- cur [i ]= 0 ;
1087- }
1096+ nanswers *= (arginh [i ].nsupers + 1 );
10881097
1089- iter = result = (Oid * * )palloc (sizeof (Oid * )* nanswers );
1098+ /*
1099+ * We also need an extra slot for the terminating NULL in the result
1100+ * array, but that cancels out with the fact that we don't want to
1101+ * generate the zero-changes case. So we need exactly nanswers slots.
1102+ */
1103+ result = (Oid * * )palloc (sizeof (Oid * )* nanswers );
1104+ j = 0 ;
1105+
1106+ /*
1107+ * Compute the cross product from right to left. When cur[i] == 0,
1108+ * generate the original input type at position i. When cur[i] == k
1109+ * for k > 0, generate its k'th supertype.
1110+ */
1111+ MemSet (cur ,0 ,sizeof (cur ));
10901112
1091- /* compute the cross product from right to left */
10921113for (;;)
10931114{
1094- oneres = (Oid * )palloc0 (FUNC_MAX_ARGS * sizeof (Oid ));
1095-
1096- for (i = nargs - 1 ;i >=0 && cur [i ]> arginh [i ].nsupers ;i -- )
1097- continue ;
1115+ /*
1116+ * Find a column we can increment. All the columns after it get
1117+ * reset to zero. (Essentially, we're adding one to the multi-
1118+ * digit number represented by cur[].)
1119+ */
1120+ for (i = nargs - 1 ;i >=0 && cur [i ] >=arginh [i ].nsupers ;i -- )
1121+ cur [i ]= 0 ;
10981122
1099- /* if we're done, terminate with NULL pointer */
1123+ /* ifnone, we're done */
11001124if (i < 0 )
1101- {
1102- * iter = NULL ;
1103- return result ;
1104- }
1125+ break ;
11051126
1106- /* no, increment this column and zero the ones after it */
1107- cur [i ]= cur [i ]+ 1 ;
1108- for (j = nargs - 1 ;j > i ;j -- )
1109- cur [j ]= 0 ;
1127+ /* increment this column */
1128+ cur [i ]+= 1 ;
1129+
1130+ /* Generate the proper output type-OID vector */
1131+ oneres = (Oid * )palloc0 (FUNC_MAX_ARGS * sizeof (Oid ));
11101132
11111133for (i = 0 ;i < nargs ;i ++ )
11121134{
11131135if (cur [i ]== 0 )
11141136oneres [i ]= arginh [i ].self ;
1115- else if (cur [i ]> arginh [i ].nsupers )
1116- oneres [i ]= 0 ;/* wild card */
11171137else
11181138oneres [i ]= arginh [i ].supervec [cur [i ]- 1 ];
11191139}
11201140
1121- * iter ++ = oneres ;
1141+ result [ j ++ ] = oneres ;
11221142}
1143+
1144+ /* terminate result vector with NULL pointer */
1145+ result [j ++ ]= NULL ;
1146+
1147+ Assert (j == nanswers );
1148+
1149+ return result ;
11231150}
11241151
11251152