88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.136 2001/07/16 05:06:57 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.137 2001/08/04 19:38:59 momjian Exp $
1212 *
1313 * NOTES
1414 * The PerformAddAttribute() code, like most of the relation
@@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel)
19841984MAXALIGN (data_length );
19851985return (tuple_length > TOAST_TUPLE_THRESHOLD );
19861986}
1987-
1988-
1987+
19891988/*
19901989 *
19911990 * LOCK TABLE
@@ -1994,26 +1993,104 @@ needs_toast_table(Relation rel)
19941993void
19951994LockTableCommand (LockStmt * lockstmt )
19961995{
1997- Relation rel ;
1998- int aclresult ;
1996+ int relCnt ;
19991997
2000- rel = heap_openr (lockstmt -> relname , NoLock );
1998+ relCnt = length (lockstmt -> rellist );
20011999
2002- if ( rel -> rd_rel -> relkind != RELKIND_RELATION )
2003- elog ( ERROR , "LOCK TABLE: %s is not a table" , lockstmt -> relname );
2000+ /* Handle a single relation lock specially to avoid overhead on likely the
2001+ most common case */
20042002
2005- if (lockstmt -> mode == AccessShareLock )
2006- aclresult = pg_aclcheck (lockstmt -> relname ,GetUserId (),ACL_SELECT );
2007- else
2008- aclresult = pg_aclcheck (lockstmt -> relname ,GetUserId (),
2009- ACL_UPDATE |ACL_DELETE );
2003+ if (relCnt == 1 )
2004+ {
2005+
2006+ /* Locking a single table */
2007+
2008+ Relation rel ;
2009+ int aclresult ;
2010+ char * relname ;
2011+
2012+ relname = strVal (lfirst (lockstmt -> rellist ));
2013+
2014+ freeList (lockstmt -> rellist );
2015+
2016+ rel = heap_openr (relname ,NoLock );
2017+
2018+ if (rel -> rd_rel -> relkind != RELKIND_RELATION )
2019+ elog (ERROR ,"LOCK TABLE: %s is not a table" ,relname );
2020+
2021+ if (lockstmt -> mode == AccessShareLock )
2022+ aclresult = pg_aclcheck (relname ,GetUserId (),
2023+ ACL_SELECT );
2024+ else
2025+ aclresult = pg_aclcheck (relname ,GetUserId (),
2026+ ACL_UPDATE |ACL_DELETE );
2027+
2028+ if (aclresult != ACLCHECK_OK )
2029+ elog (ERROR ,"LOCK TABLE: permission denied" );
2030+
2031+ LockRelation (rel ,lockstmt -> mode );
2032+
2033+ pfree (relname );
2034+
2035+ heap_close (rel ,NoLock );/* close rel, keep lock */
2036+ }
2037+ else
2038+ {
2039+ List * p ;
2040+ Relation * RelationArray ;
2041+ Relation * pRel ;
20102042
2011- if (aclresult != ACLCHECK_OK )
2012- elog (ERROR ,"LOCK TABLE: permission denied" );
2043+ /* Locking multiple tables */
20132044
2014- LockRelation ( rel , lockstmt -> mode );
2045+ /* Create an array of relations */
20152046
2016- heap_close (rel ,NoLock );/* close rel, keep lock */
2047+ RelationArray = palloc (relCnt * sizeof (Relation ));
2048+ pRel = RelationArray ;
2049+
2050+ /* Iterate over the list and populate the relation array */
2051+
2052+ foreach (p ,lockstmt -> rellist )
2053+ {
2054+ char * relname = strVal (lfirst (p ));
2055+ int aclresult ;
2056+
2057+ * pRel = heap_openr (relname ,NoLock );
2058+
2059+ if ((* pRel )-> rd_rel -> relkind != RELKIND_RELATION )
2060+ elog (ERROR ,"LOCK TABLE: %s is not a table" ,
2061+ relname );
2062+
2063+ if (lockstmt -> mode == AccessShareLock )
2064+ aclresult = pg_aclcheck (relname ,GetUserId (),
2065+ ACL_SELECT );
2066+ else
2067+ aclresult = pg_aclcheck (relname ,GetUserId (),
2068+ ACL_UPDATE |ACL_DELETE );
2069+
2070+ if (aclresult != ACLCHECK_OK )
2071+ elog (ERROR ,"LOCK TABLE: permission denied" );
2072+
2073+ pRel ++ ;
2074+ pfree (relname );
2075+ }
2076+
2077+ /* Now, lock all the relations, closing each after it is locked
2078+ (Keeping the locks)
2079+ */
2080+
2081+ for (pRel = RelationArray ;
2082+ pRel < RelationArray + relCnt ;
2083+ pRel ++ )
2084+ {
2085+ LockRelation (* pRel ,lockstmt -> mode );
2086+
2087+ heap_close (* pRel ,NoLock );
2088+ }
2089+
2090+ /* Free the relation array */
2091+
2092+ pfree (RelationArray );
2093+ }
20172094}
20182095
20192096