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

Commit0332d65

Browse files
committed
Implement partial-key searching of syscaches, per recent suggestion
to pghackers. Use this to do searching for ambiguous functions ---it will get more uses soon.
1 parent707cf12 commit0332d65

File tree

7 files changed

+891
-341
lines changed

7 files changed

+891
-341
lines changed

‎src/backend/catalog/namespace.c

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.5 2002/04/01 03:34:25 tgl Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.6 2002/04/06 06:59:21 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -26,13 +26,15 @@
2626
#include"catalog/namespace.h"
2727
#include"catalog/pg_inherits.h"
2828
#include"catalog/pg_namespace.h"
29+
#include"catalog/pg_proc.h"
2930
#include"catalog/pg_shadow.h"
3031
#include"miscadmin.h"
3132
#include"nodes/makefuncs.h"
3233
#include"storage/backendid.h"
3334
#include"utils/builtins.h"
3435
#include"utils/fmgroids.h"
3536
#include"utils/guc.h"
37+
#include"utils/catcache.h"
3638
#include"utils/lsyscache.h"
3739
#include"utils/syscache.h"
3840

@@ -301,6 +303,174 @@ TypenameGetTypid(const char *typname)
301303
returnInvalidOid;
302304
}
303305

306+
/*
307+
* FuncnameGetCandidates
308+
*Given a possibly-qualified function name and argument count,
309+
*retrieve a list of the possible matches.
310+
*
311+
* We search a single namespace if the function name is qualified, else
312+
* all namespaces in the search path. The return list will never contain
313+
* multiple entries with identical argument types --- in the multiple-
314+
* namespace case, we arrange for entries in earlier namespaces to mask
315+
* identical entries in later namespaces.
316+
*/
317+
FuncCandidateList
318+
FuncnameGetCandidates(List*names,intnargs)
319+
{
320+
FuncCandidateListresultList=NULL;
321+
char*catalogname;
322+
char*schemaname=NULL;
323+
char*funcname=NULL;
324+
OidnamespaceId;
325+
CatCList*catlist;
326+
inti;
327+
328+
/* deconstruct the name list */
329+
switch (length(names))
330+
{
331+
case1:
332+
funcname=strVal(lfirst(names));
333+
break;
334+
case2:
335+
schemaname=strVal(lfirst(names));
336+
funcname=strVal(lsecond(names));
337+
break;
338+
case3:
339+
catalogname=strVal(lfirst(names));
340+
schemaname=strVal(lsecond(names));
341+
funcname=strVal(lfirst(lnext(lnext(names))));
342+
/*
343+
* We check the catalog name and then ignore it.
344+
*/
345+
if (strcmp(catalogname,DatabaseName)!=0)
346+
elog(ERROR,"Cross-database references are not implemented");
347+
break;
348+
default:
349+
elog(ERROR,"Improper qualified name (too many dotted names)");
350+
break;
351+
}
352+
353+
if (schemaname)
354+
{
355+
/* use exact schema given */
356+
namespaceId=GetSysCacheOid(NAMESPACENAME,
357+
CStringGetDatum(schemaname),
358+
0,0,0);
359+
if (!OidIsValid(namespaceId))
360+
elog(ERROR,"Namespace \"%s\" does not exist",
361+
schemaname);
362+
}
363+
else
364+
{
365+
/* flag to indicate we need namespace search */
366+
namespaceId=InvalidOid;
367+
}
368+
369+
/* Search syscache by name and nargs only */
370+
catlist=SearchSysCacheList(PROCNAME,2,
371+
CStringGetDatum(funcname),
372+
Int16GetDatum(nargs),
373+
0,0);
374+
375+
for (i=0;i<catlist->n_members;i++)
376+
{
377+
HeapTupleproctup=&catlist->members[i]->tuple;
378+
Form_pg_procprocform= (Form_pg_proc)GETSTRUCT(proctup);
379+
intpathpos=0;
380+
FuncCandidateListnewResult;
381+
382+
if (OidIsValid(namespaceId))
383+
{
384+
/* Consider only procs in specified namespace */
385+
if (procform->pronamespace!=namespaceId)
386+
continue;
387+
/* No need to check args, they must all be different */
388+
}
389+
else
390+
{
391+
/* Consider only procs that are in the search path */
392+
if (pathContainsSystemNamespace||
393+
procform->pronamespace!=PG_CATALOG_NAMESPACE)
394+
{
395+
List*nsp;
396+
397+
foreach(nsp,namespaceSearchPath)
398+
{
399+
pathpos++;
400+
if (procform->pronamespace== (Oid)lfirsti(nsp))
401+
break;
402+
}
403+
if (nsp==NIL)
404+
continue;/* proc is not in search path */
405+
}
406+
407+
/*
408+
* Okay, it's in the search path, but does it have the same
409+
* arguments as something we already accepted? If so, keep
410+
* only the one that appears earlier in the search path.
411+
*
412+
* If we have an ordered list from SearchSysCacheList (the
413+
* normal case), then any conflicting proc must immediately
414+
* adjoin this one in the list, so we only need to look at
415+
* the newest result item. If we have an unordered list,
416+
* we have to scan the whole result list.
417+
*/
418+
if (resultList)
419+
{
420+
FuncCandidateListprevResult;
421+
422+
if (catlist->ordered)
423+
{
424+
if (memcmp(procform->proargtypes,resultList->args,
425+
nargs*sizeof(Oid))==0)
426+
prevResult=resultList;
427+
else
428+
prevResult=NULL;
429+
}
430+
else
431+
{
432+
for (prevResult=resultList;
433+
prevResult;
434+
prevResult=prevResult->next)
435+
{
436+
if (memcmp(procform->proargtypes,prevResult->args,
437+
nargs*sizeof(Oid))==0)
438+
break;
439+
}
440+
}
441+
if (prevResult)
442+
{
443+
/* We have a match with a previous result */
444+
Assert(pathpos!=prevResult->pathpos);
445+
if (pathpos>prevResult->pathpos)
446+
continue;/* keep previous result */
447+
/* replace previous result */
448+
prevResult->pathpos=pathpos;
449+
prevResult->oid=proctup->t_data->t_oid;
450+
continue;/* args are same, of course */
451+
}
452+
}
453+
}
454+
455+
/*
456+
* Okay to add it to result list
457+
*/
458+
newResult= (FuncCandidateList)
459+
palloc(sizeof(struct_FuncCandidateList)-sizeof(Oid)
460+
+nargs*sizeof(Oid));
461+
newResult->pathpos=pathpos;
462+
newResult->oid=proctup->t_data->t_oid;
463+
memcpy(newResult->args,procform->proargtypes,nargs*sizeof(Oid));
464+
465+
newResult->next=resultList;
466+
resultList=newResult;
467+
}
468+
469+
ReleaseSysCacheList(catlist);
470+
471+
returnresultList;
472+
}
473+
304474
/*
305475
* QualifiedNameGetCreationNamespace
306476
*Given a possibly-qualified name for an object (in List-of-Values

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp