@@ -659,147 +659,77 @@ ExecGrantStmt_oids(InternalGrant *istmt)
659659 * objectNamesToOids
660660 *
661661 * Turn a list of object names of a given type into an Oid list.
662- *
663- * XXX: This function doesn't take any sort of locks on the objects whose
664- * names it looks up. In the face of concurrent DDL, we might easily latch
665- * onto an old version of an object, causing the GRANT or REVOKE statement
666- * to fail.
667662 */
668663static List *
669664objectNamesToOids (ObjectType objtype ,List * objnames ,bool is_grant )
670665{
671666List * objects = NIL ;
672667ListCell * cell ;
668+ const LOCKMODE lockmode = AccessShareLock ;
673669
674670Assert (objnames != NIL );
675671
676672switch (objtype )
677673{
678- case OBJECT_TABLE :
679- case OBJECT_SEQUENCE :
680- foreach (cell ,objnames )
681- {
682- RangeVar * relvar = (RangeVar * )lfirst (cell );
683- Oid relOid ;
684-
685- relOid = RangeVarGetRelid (relvar ,NoLock , false);
686- objects = lappend_oid (objects ,relOid );
687- }
688- break ;
689- case OBJECT_DATABASE :
690- foreach (cell ,objnames )
691- {
692- char * dbname = strVal (lfirst (cell ));
693- Oid dbid ;
694-
695- dbid = get_database_oid (dbname , false);
696- objects = lappend_oid (objects ,dbid );
697- }
698- break ;
699- case OBJECT_DOMAIN :
700- case OBJECT_TYPE :
701- foreach (cell ,objnames )
702- {
703- List * typname = (List * )lfirst (cell );
704- Oid oid ;
705-
706- oid = typenameTypeId (NULL ,makeTypeNameFromNameList (typname ));
707- objects = lappend_oid (objects ,oid );
708- }
709- break ;
710- case OBJECT_FUNCTION :
711- foreach (cell ,objnames )
712- {
713- ObjectWithArgs * func = (ObjectWithArgs * )lfirst (cell );
714- Oid funcid ;
674+ default :
715675
716- funcid = LookupFuncWithArgs (OBJECT_FUNCTION ,func , false);
717- objects = lappend_oid (objects ,funcid );
718- }
719- break ;
720- case OBJECT_LANGUAGE :
676+ /*
677+ * For most object types, we use get_object_address() directly.
678+ */
721679foreach (cell ,objnames )
722680{
723- char * langname = strVal (lfirst (cell ));
724- Oid oid ;
681+ ObjectAddress address ;
725682
726- oid = get_language_oid ( langname , false);
727- objects = lappend_oid (objects ,oid );
683+ address = get_object_address ( objtype , lfirst ( cell ), NULL , lockmode , false);
684+ objects = lappend_oid (objects ,address . objectId );
728685}
729686break ;
730- case OBJECT_LARGEOBJECT :
731- foreach (cell ,objnames )
732- {
733- Oid lobjOid = oidparse (lfirst (cell ));
734687
735- if (!LargeObjectExists (lobjOid ))
736- ereport (ERROR ,
737- (errcode (ERRCODE_UNDEFINED_OBJECT ),
738- errmsg ("large object %u does not exist" ,
739- lobjOid )));
740-
741- objects = lappend_oid (objects ,lobjOid );
742- }
743- break ;
744- case OBJECT_SCHEMA :
745- foreach (cell ,objnames )
746- {
747- char * nspname = strVal (lfirst (cell ));
748- Oid oid ;
688+ case OBJECT_TABLE :
689+ case OBJECT_SEQUENCE :
749690
750- oid = get_namespace_oid ( nspname , false);
751- objects = lappend_oid ( objects , oid );
752- }
753- break ;
754- case OBJECT_PROCEDURE :
691+ /*
692+ * Here, we don't use get_object_address(). It requires that the
693+ * specified object type match the actual type of the object, but
694+ * in GRANT/REVOKE, all table-like things are addressed as TABLE.
695+ */
755696foreach (cell ,objnames )
756697{
757- ObjectWithArgs * func = (ObjectWithArgs * )lfirst (cell );
758- Oid procid ;
698+ RangeVar * relvar = (RangeVar * )lfirst (cell );
699+ Oid relOid ;
759700
760- procid = LookupFuncWithArgs ( OBJECT_PROCEDURE , func , false);
761- objects = lappend_oid (objects ,procid );
701+ relOid = RangeVarGetRelid ( relvar , lockmode , false);
702+ objects = lappend_oid (objects ,relOid );
762703}
763704break ;
764- case OBJECT_ROUTINE :
765- foreach (cell ,objnames )
766- {
767- ObjectWithArgs * func = (ObjectWithArgs * )lfirst (cell );
768- Oid routid ;
769705
770- routid = LookupFuncWithArgs (OBJECT_ROUTINE ,func , false);
771- objects = lappend_oid (objects ,routid );
772- }
773- break ;
774- case OBJECT_TABLESPACE :
775- foreach (cell ,objnames )
776- {
777- char * spcname = strVal (lfirst (cell ));
778- Oid spcoid ;
706+ case OBJECT_DOMAIN :
707+ case OBJECT_TYPE :
779708
780- spcoid = get_tablespace_oid (spcname , false);
781- objects = lappend_oid (objects ,spcoid );
782- }
783- break ;
784- case OBJECT_FDW :
709+ /*
710+ * The parse representation of types and domains in privilege
711+ * targets is different from that expected by get_object_address()
712+ * (for parse conflict reasons), so we have to do a bit of
713+ * conversion here.
714+ */
785715foreach (cell ,objnames )
786716{
787- char * fdwname = strVal (lfirst (cell ));
788- Oid fdwid = get_foreign_data_wrapper_oid (fdwname , false);
717+ List * typname = (List * )lfirst (cell );
718+ TypeName * tn = makeTypeNameFromNameList (typname );
719+ ObjectAddress address ;
720+ Relation relation ;
789721
790- objects = lappend_oid (objects ,fdwid );
722+ address = get_object_address (objtype , (Node * )tn ,& relation ,lockmode , false);
723+ Assert (relation == NULL );
724+ objects = lappend_oid (objects ,address .objectId );
791725}
792726break ;
793- case OBJECT_FOREIGN_SERVER :
794- foreach (cell ,objnames )
795- {
796- char * srvname = strVal (lfirst (cell ));
797- Oid srvid = get_foreign_server_oid (srvname , false);
798727
799- objects = lappend_oid (objects ,srvid );
800- }
801- break ;
802728case OBJECT_PARAMETER_ACL :
729+
730+ /*
731+ * Parameters are handled completely differently.
732+ */
803733foreach (cell ,objnames )
804734{
805735/*
@@ -830,9 +760,6 @@ objectNamesToOids(ObjectType objtype, List *objnames, bool is_grant)
830760objects = lappend_oid (objects ,parameterId );
831761}
832762break ;
833- default :
834- elog (ERROR ,"unrecognized GrantStmt.objtype: %d" ,
835- (int )objtype );
836763}
837764
838765return objects ;
@@ -2458,14 +2385,6 @@ ExecGrant_Type_check(InternalGrant *istmt, HeapTuple tuple)
24582385(errcode (ERRCODE_INVALID_GRANT_OPERATION ),
24592386errmsg ("cannot set privileges of multirange types" ),
24602387errhint ("Set the privileges of the range type instead." )));
2461-
2462- /* Used GRANT DOMAIN on a non-domain? */
2463- if (istmt -> objtype == OBJECT_DOMAIN &&
2464- pg_type_tuple -> typtype != TYPTYPE_DOMAIN )
2465- ereport (ERROR ,
2466- (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
2467- errmsg ("\"%s\" is not a domain" ,
2468- NameStr (pg_type_tuple -> typname ))));
24692388}
24702389
24712390static void