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

Commit5cf18b1

Browse files
committed
Don't generate 'zero' typeids in the output from gen_cross_product.
This is no longer necessary or appropriate since we don't use zero typeidas a wildcard anymore, and it fixes a nasty performance problem withfunctions with many parameters. Per recent example from Reuven Lerner.
1 parent91e6f51 commit5cf18b1

File tree

1 file changed

+76
-49
lines changed

1 file changed

+76
-49
lines changed

‎src/backend/parser/parse_func.c

Lines changed: 76 additions & 49 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.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
*/
946952
staticOid**
947953
argtype_inherit(intnargs,Oid*argtypes)
@@ -950,22 +956,13 @@ argtype_inherit(int nargs, Oid *argtypes)
950956
inti;
951957
InhPathsarginh[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));
966964
else
967965
{
968-
arginh[i].self=InvalidOid;
969966
arginh[i].nsupers=0;
970967
arginh[i].supervec= (Oid*)NULL;
971968
}
@@ -975,6 +972,13 @@ argtype_inherit(int nargs, Oid *argtypes)
975972
returngen_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+
*/
978982
staticint
979983
find_inheritors(Oidrelid,Oid**supervec)
980984
{
@@ -1068,58 +1072,81 @@ find_inheritors(Oid relid, Oid **supervec)
10681072
returnnvisited;
10691073
}
10701074

1075+
/*
1076+
* Generate the ordered list of substitute argtype vectors to try.
1077+
*
1078+
* See comments for argtype_inherit.
1079+
*/
10711080
staticOid**
10721081
gen_cross_product(InhPaths*arginh,intnargs)
10731082
{
10741083
intnanswers;
1075-
Oid**result,
1076-
**iter;
1084+
Oid**result;
10771085
Oid*oneres;
10781086
inti,
10791087
j;
10801088
intcur[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+
*/
10821094
nanswers=1;
10831095
for (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 */
10921113
for (;;)
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 */
11001124
if (i<0)
1101-
{
1102-
*iter=NULL;
1103-
returnresult;
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

11111133
for (i=0;i<nargs;i++)
11121134
{
11131135
if (cur[i]==0)
11141136
oneres[i]=arginh[i].self;
1115-
elseif (cur[i]>arginh[i].nsupers)
1116-
oneres[i]=0;/* wild card */
11171137
else
11181138
oneres[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+
returnresult;
11231150
}
11241151

11251152

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp