001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.DropTriggerConstantAction
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.execute;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025:
026: import org.apache.derby.iapi.error.StandardException;
027: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
028:
029: import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
030: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
031: import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
032: import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
033: import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
034: import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
035: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
036:
037: import org.apache.derby.iapi.sql.depend.DependencyManager;
038:
039: import org.apache.derby.iapi.reference.SQLState;
040:
041: import org.apache.derby.iapi.sql.execute.ConstantAction;
042:
043: import org.apache.derby.iapi.sql.Activation;
044:
045: import org.apache.derby.iapi.store.access.TransactionController;
046:
047: import org.apache.derby.catalog.UUID;
048:
049: /**
050: * This class describes actions that are ALWAYS performed for a
051: * DROP TRIGGER Statement at Execution time.
052: *
053: * @author Jamie
054: */
055: public class DropTriggerConstantAction extends
056: DDLSingleTableConstantAction {
057:
058: private final String triggerName;
059: private final SchemaDescriptor sd;
060:
061: // CONSTRUCTORS
062:
063: /**
064: * Make the ConstantAction for a DROP TRIGGER statement.
065: *
066: * @param sd Schema that stored prepared statement lives in.
067: * @param triggerName Name of the Trigger
068: * @param tableId The table upon which the trigger is defined
069: *
070: */
071: DropTriggerConstantAction(SchemaDescriptor sd, String triggerName,
072: UUID tableId) {
073: super (tableId);
074: this .sd = sd;
075: this .triggerName = triggerName;
076:
077: if (SanityManager.DEBUG) {
078: SanityManager
079: .ASSERT(sd != null, "SchemaDescriptor is null");
080: }
081: }
082:
083: /**
084: * This is the guts of the Execution-time logic for DROP STATEMENT.
085: *
086: * @see ConstantAction#executeConstantAction
087: *
088: * @exception StandardException Thrown on failure
089: */
090: public void executeConstantAction(Activation activation)
091: throws StandardException {
092: TriggerDescriptor triggerd;
093:
094: LanguageConnectionContext lcc = activation
095: .getLanguageConnectionContext();
096: DataDictionary dd = lcc.getDataDictionary();
097: DependencyManager dm = dd.getDependencyManager();
098:
099: /*
100: ** Inform the data dictionary that we are about to write to it.
101: ** There are several calls to data dictionary "get" methods here
102: ** that might be done in "read" mode in the data dictionary, but
103: ** it seemed safer to do this whole operation in "write" mode.
104: **
105: ** We tell the data dictionary we're done writing at the end of
106: ** the transaction.
107: */
108: dd.startWriting(lcc);
109:
110: TableDescriptor td = dd.getTableDescriptor(tableId);
111: if (td == null) {
112: throw StandardException.newException(
113: SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION,
114: tableId.toString());
115: }
116: TransactionController tc = lcc.getTransactionExecute();
117: lockTableForDDL(tc, td.getHeapConglomerateId(), true);
118: // get td again in case table shape is changed before lock is acquired
119: td = dd.getTableDescriptor(tableId);
120: if (td == null) {
121: throw StandardException.newException(
122: SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION,
123: tableId.toString());
124: }
125:
126: /*
127: ** Get the trigger descriptor. We're responsible for raising
128: ** the error if it isn't found
129: */
130: triggerd = dd.getTriggerDescriptor(triggerName, sd);
131:
132: if (triggerd == null) {
133: throw StandardException
134: .newException(
135: SQLState.LANG_OBJECT_NOT_FOUND_DURING_EXECUTION,
136: "TRIGGER",
137: (sd.getSchemaName() + "." + triggerName));
138: }
139:
140: /*
141: ** Prepare all dependents to invalidate. (This is there chance
142: ** to say that they can't be invalidated. For example, an open
143: ** cursor referencing a table/trigger that the user is attempting to
144: ** drop.) If no one objects, then invalidate any dependent objects.
145: */
146: dropTriggerDescriptor(lcc, dm, dd, tc, triggerd, activation);
147: }
148:
149: public static void dropTriggerDescriptor(
150: LanguageConnectionContext lcc, DependencyManager dm,
151: DataDictionary dd, TransactionController tc,
152: TriggerDescriptor triggerd, Activation activation)
153: throws StandardException {
154: if (SanityManager.DEBUG) {
155: SanityManager.ASSERT(triggerd != null,
156: "trigger descriptor is null");
157: }
158:
159: dm.invalidateFor(triggerd, DependencyManager.DROP_TRIGGER, lcc);
160:
161: // Drop the trigger
162: dd.dropTriggerDescriptor(triggerd, tc);
163:
164: // Clear the dependencies for the trigger
165: dm.clearDependencies(lcc, triggerd);
166:
167: // Drop the spses
168: SPSDescriptor spsd = dd
169: .getSPSDescriptor(triggerd.getActionId());
170:
171: // there shouldn't be any dependencies, but in case
172: // there are, lets clear them
173: dm.invalidateFor(spsd, DependencyManager.DROP_TRIGGER, lcc);
174: dm.clearDependencies(lcc, spsd);
175: dd.dropSPSDescriptor(spsd, tc);
176:
177: if (triggerd.getWhenClauseId() != null) {
178: spsd = dd.getSPSDescriptor(triggerd.getWhenClauseId());
179: dm.invalidateFor(spsd, DependencyManager.DROP_TRIGGER, lcc);
180: dm.clearDependencies(lcc, spsd);
181: dd.dropSPSDescriptor(spsd, tc);
182: }
183: }
184:
185: public String toString() {
186: // Do not put this under SanityManager.DEBUG - it is needed for
187: // error reporting.
188: return "DROP TRIGGER " + triggerName;
189: }
190: }
|