8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
* NOTES
14
14
* The PerformAddAttribute() code, like most of the relation
@@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel)
1984
1984
MAXALIGN (data_length );
1985
1985
return (tuple_length > TOAST_TUPLE_THRESHOLD );
1986
1986
}
1987
-
1988
-
1987
+
1989
1988
/*
1990
1989
*
1991
1990
* LOCK TABLE
@@ -1994,26 +1993,104 @@ needs_toast_table(Relation rel)
1994
1993
void
1995
1994
LockTableCommand (LockStmt * lockstmt )
1996
1995
{
1997
- Relation rel ;
1998
- int aclresult ;
1996
+ int relCnt ;
1999
1997
2000
- rel = heap_openr (lockstmt -> relname , NoLock );
1998
+ relCnt = length (lockstmt -> rellist );
2001
1999
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 */
2004
2002
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 ;
2010
2042
2011
- if (aclresult != ACLCHECK_OK )
2012
- elog (ERROR , "LOCK TABLE: permission denied" );
2043
+ /* Locking multiple tables */
2013
2044
2014
- LockRelation ( rel , lockstmt -> mode );
2045
+ /* Create an array of relations */
2015
2046
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
+ }
2017
2094
}
2018
2095
2019
2096
0 commit comments