--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.compile.TablePrivilegesNode\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.compile;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.impl.sql.execute.PrivilegeInfo;\r
+import org.apache.derby.impl.sql.execute.TablePrivilegeInfo;\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.depend.Provider;\r
+import org.apache.derby.iapi.sql.depend.ProviderInfo;\r
+import org.apache.derby.iapi.sql.depend.ProviderList;\r
+import org.apache.derby.iapi.sql.conn.ConnectionUtil;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * This class represents a set of privileges on one table.\r
+ */\r
+public class TablePrivilegesNode extends QueryTreeNode\r
+{\r
+ private boolean[] actionAllowed = new boolean[ TablePrivilegeInfo.ACTION_COUNT];\r
+ private ResultColumnList[] columnLists = new ResultColumnList[ TablePrivilegeInfo.ACTION_COUNT];\r
+ private FormatableBitSet[] columnBitSets = new FormatableBitSet[ TablePrivilegeInfo.ACTION_COUNT];\r
+ private TableDescriptor td; \r
+ private List descriptorList; \r
+ \r
+ /**\r
+ * Add all actions\r
+ */\r
+ public void addAll()\r
+ {\r
+ for( int i = 0; i < TablePrivilegeInfo.ACTION_COUNT; i++)\r
+ {\r
+ actionAllowed[i] = true;\r
+ columnLists[i] = null;\r
+ }\r
+ } // end of addAll\r
+\r
+ /**\r
+ * Add one action to the privileges for this table\r
+ *\r
+ * @param action The action type\r
+ * @param privilegeColumnList The set of privilege columns. Null for all columns\r
+ *\r
+ * @exception StandardException standard error policy.\r
+ */\r
+ public void addAction( int action, ResultColumnList privilegeColumnList)\r
+ {\r
+ actionAllowed[ action] = true;\r
+ if( privilegeColumnList == null)\r
+ columnLists[ action] = null;\r
+ else if( columnLists[ action] == null)\r
+ columnLists[ action] = privilegeColumnList;\r
+ else\r
+ columnLists[ action].appendResultColumns( privilegeColumnList, false);\r
+ } // end of addAction\r
+\r
+ /**\r
+ * Bind.\r
+ *\r
+ * @param td The table descriptor\r
+ * @param isGrant grant if true; revoke if false\r
+ */\r
+ public void bind( TableDescriptor td, boolean isGrant) throws StandardException\r
+ {\r
+ this.td = td;\r
+ \r
+ for( int action = 0; action < TablePrivilegeInfo.ACTION_COUNT; action++)\r
+ {\r
+ if( columnLists[ action] != null)\r
+ columnBitSets[action] = columnLists[ action].bindResultColumnsByName( td, (DMLStatementNode) null);\r
+\r
+ // Prevent granting non-SELECT privileges to views\r
+ if (td.getTableType() == TableDescriptor.VIEW_TYPE && action != TablePrivilegeInfo.SELECT_ACTION)\r
+ if (actionAllowed[action])\r
+ throw StandardException.newException(SQLState.AUTH_GRANT_REVOKE_NOT_ALLOWED,\r
+ td.getQualifiedName());\r
+ }\r
+ \r
+ if (isGrant && td.getTableType() == TableDescriptor.VIEW_TYPE)\r
+ {\r
+ bindPrivilegesForView(td);\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * @return PrivilegeInfo for this node\r
+ */\r
+ public PrivilegeInfo makePrivilegeInfo()\r
+ {\r
+ return new TablePrivilegeInfo( td, actionAllowed, columnBitSets, \r
+ descriptorList);\r
+ }\r
+ \r
+ /**\r
+ * Retrieve all the underlying stored dependencies such as table(s), \r
+ * view(s) and routine(s) descriptors which the view depends on.\r
+ * This information is then passed to the runtime to determine if\r
+ * the privilege is grantable to the grantees by this grantor at\r
+ * execution time.\r
+ * \r
+ * Go through the providers regardless who the grantor is since \r
+ * the statement cache may be in effect.\r
+ * \r
+ * @param td the TableDescriptor to check\r
+ *\r
+ * @exception StandardException standard error policy.\r
+ */\r
+ private void bindPrivilegesForView ( TableDescriptor td) \r
+ throws StandardException\r
+ {\r
+ LanguageConnectionContext lcc = getLanguageConnectionContext();\r
+ DataDictionary dd = lcc.getDataDictionary();\r
+ ViewDescriptor vd = dd.getViewDescriptor(td);\r
+ DependencyManager dm = dd.getDependencyManager();\r
+ ProviderInfo[] pis = dm.getPersistentProviderInfos(vd);\r
+ this.descriptorList = new ArrayList();\r
+ \r
+ int siz = pis.length;\r
+ for (int i=0; i < siz; i++) \r
+ {\r
+ Provider provider = (Provider) pis[i].getDependableFinder().getDependable(dd, pis[i].getObjectId());\r
+ \r
+ if (provider instanceof TableDescriptor || \r
+ provider instanceof ViewDescriptor ||\r
+ provider instanceof AliasDescriptor)\r
+ {\r
+ descriptorList.add(provider);\r
+ } \r
+ }\r
+ }\r
+ \r
+}\r
+ \r