|
13 | 13 | * Portions Copyright (c) 1994, Regents of the University of California
|
14 | 14 | *
|
15 | 15 | * IDENTIFICATION
|
16 |
| - * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.84 2006/04/25 14:11:53 momjian Exp $ |
| 16 | + * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.85 2006/05/01 23:22:43 tgl Exp $ |
17 | 17 | *
|
18 | 18 | *-------------------------------------------------------------------------
|
19 | 19 | */
|
@@ -682,6 +682,95 @@ FunctionIsVisible(Oid funcid)
|
682 | 682 | }
|
683 | 683 |
|
684 | 684 |
|
| 685 | +/* |
| 686 | + * OpernameGetOprid |
| 687 | + *Given a possibly-qualified operator name and exact input datatypes, |
| 688 | + *look up the operator. Returns InvalidOid if not found. |
| 689 | + * |
| 690 | + * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for |
| 691 | + * a postfix op. |
| 692 | + * |
| 693 | + * If the operator name is not schema-qualified, it is sought in the current |
| 694 | + * namespace search path. |
| 695 | + */ |
| 696 | +Oid |
| 697 | +OpernameGetOprid(List*names,Oidoprleft,Oidoprright) |
| 698 | +{ |
| 699 | +char*schemaname; |
| 700 | +char*opername; |
| 701 | +CatCList*catlist; |
| 702 | +ListCell*l; |
| 703 | + |
| 704 | +/* deconstruct the name list */ |
| 705 | +DeconstructQualifiedName(names,&schemaname,&opername); |
| 706 | + |
| 707 | +if (schemaname) |
| 708 | +{ |
| 709 | +/* search only in exact schema given */ |
| 710 | +OidnamespaceId; |
| 711 | +HeapTupleopertup; |
| 712 | + |
| 713 | +namespaceId=LookupExplicitNamespace(schemaname); |
| 714 | +opertup=SearchSysCache(OPERNAMENSP, |
| 715 | +CStringGetDatum(opername), |
| 716 | +ObjectIdGetDatum(oprleft), |
| 717 | +ObjectIdGetDatum(oprright), |
| 718 | +ObjectIdGetDatum(namespaceId)); |
| 719 | +if (HeapTupleIsValid(opertup)) |
| 720 | +{ |
| 721 | +Oidresult=HeapTupleGetOid(opertup); |
| 722 | + |
| 723 | +ReleaseSysCache(opertup); |
| 724 | +returnresult; |
| 725 | +} |
| 726 | +returnInvalidOid; |
| 727 | +} |
| 728 | + |
| 729 | +/* Search syscache by name and argument types */ |
| 730 | +catlist=SearchSysCacheList(OPERNAMENSP,3, |
| 731 | +CStringGetDatum(opername), |
| 732 | +ObjectIdGetDatum(oprleft), |
| 733 | +ObjectIdGetDatum(oprright), |
| 734 | +0); |
| 735 | + |
| 736 | +if (catlist->n_members==0) |
| 737 | +{ |
| 738 | +/* no hope, fall out early */ |
| 739 | +ReleaseSysCacheList(catlist); |
| 740 | +returnInvalidOid; |
| 741 | +} |
| 742 | + |
| 743 | +/* |
| 744 | + * We have to find the list member that is first in the search path, |
| 745 | + * if there's more than one. This doubly-nested loop looks ugly, |
| 746 | + * but in practice there should usually be few catlist members. |
| 747 | + */ |
| 748 | +recomputeNamespacePath(); |
| 749 | + |
| 750 | +foreach(l,namespaceSearchPath) |
| 751 | +{ |
| 752 | +OidnamespaceId=lfirst_oid(l); |
| 753 | +inti; |
| 754 | + |
| 755 | +for (i=0;i<catlist->n_members;i++) |
| 756 | +{ |
| 757 | +HeapTupleopertup=&catlist->members[i]->tuple; |
| 758 | +Form_pg_operatoroperform= (Form_pg_operator)GETSTRUCT(opertup); |
| 759 | + |
| 760 | +if (operform->oprnamespace==namespaceId) |
| 761 | +{ |
| 762 | +Oidresult=HeapTupleGetOid(opertup); |
| 763 | + |
| 764 | +ReleaseSysCacheList(catlist); |
| 765 | +returnresult; |
| 766 | +} |
| 767 | +} |
| 768 | +} |
| 769 | + |
| 770 | +ReleaseSysCacheList(catlist); |
| 771 | +returnInvalidOid; |
| 772 | +} |
| 773 | + |
685 | 774 | /*
|
686 | 775 | * OpernameGetCandidates
|
687 | 776 | *Given a possibly-qualified operator name and operator kind,
|
@@ -883,26 +972,13 @@ OperatorIsVisible(Oid oprid)
|
883 | 972 | * If it is in the path, it might still not be visible; it could be
|
884 | 973 | * hidden by another operator of the same name and arguments earlier
|
885 | 974 | * in the path. So we must do a slow check to see if this is the same
|
886 |
| - * operator that would be found byOpernameGetCandidates. |
| 975 | + * operator that would be found byOpernameGetOprId. |
887 | 976 | */
|
888 | 977 | char*oprname=NameStr(oprform->oprname);
|
889 |
| -FuncCandidateListclist; |
890 |
| - |
891 |
| -visible= false; |
892 | 978 |
|
893 |
| -clist=OpernameGetCandidates(list_make1(makeString(oprname)), |
894 |
| -oprform->oprkind); |
895 |
| - |
896 |
| -for (;clist;clist=clist->next) |
897 |
| -{ |
898 |
| -if (clist->args[0]==oprform->oprleft&& |
899 |
| -clist->args[1]==oprform->oprright) |
900 |
| -{ |
901 |
| -/* Found the expected entry; is it the right op? */ |
902 |
| -visible= (clist->oid==oprid); |
903 |
| -break; |
904 |
| -} |
905 |
| -} |
| 979 | +visible= (OpernameGetOprid(list_make1(makeString(oprname)), |
| 980 | +oprform->oprleft,oprform->oprright) |
| 981 | +==oprid); |
906 | 982 | }
|
907 | 983 |
|
908 | 984 | ReleaseSysCache(oprtup);
|
|