⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 createtriggernode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*   Derby - Class org.apache.derby.impl.sql.compile.CreateTriggerNode   Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package	org.apache.derby.impl.sql.compile;import org.apache.derby.iapi.services.context.ContextManager;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.sql.compile.CompilerContext;import org.apache.derby.iapi.sql.compile.Parser;import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;import org.apache.derby.iapi.sql.dictionary.DataDictionary;import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;import org.apache.derby.iapi.sql.dictionary.TableDescriptor;import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;import org.apache.derby.iapi.sql.depend.Dependent;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.sql.execute.ConstantAction;import org.apache.derby.iapi.sql.ResultSet;import org.apache.derby.iapi.types.DataTypeDescriptor;import org.apache.derby.iapi.types.TypeId;import org.apache.derby.catalog.UUID;import java.sql.Timestamp;import java.sql.Types;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;/** * A CreateTriggerNode is the root of a QueryTree  * that represents a CREATE TRIGGER * statement. * * @author jamie */public class CreateTriggerNode extends CreateStatementNode{	private	TableName			triggerName;	private	TableName			tableName;	private	int					triggerEventMask;	private ResultColumnList	triggerCols;	private	boolean				isBefore;	private	boolean				isRow;	private	boolean				isEnabled;	private	Vector				refClause;	private	QueryTreeNode		whenClause;	private	String				whenText;	private	int					whenOffset;	private	StatementNode		actionNode;	private	String				actionText;	private	String				originalActionText; // text w/o trim of spaces	private	int					actionOffset;	private SchemaDescriptor	triggerSchemaDescriptor;	private SchemaDescriptor	compSchemaDescriptor;	private int[]				referencedColInts;	private TableDescriptor		triggerTableDescriptor;	private	UUID				actionCompSchemaId;	/*	** Names of old and new table.  By default we have	** OLD/old and NEW/new.  The casing is dependent on 	** the language connection context casing as the rest    ** of other code. Therefore we will set the value of the     ** String at the init() time.    ** However, if there is a referencing clause	** we will reset these values to be whatever the user	** wants.	*/	private String oldTableName;	private String newTableName;	private boolean oldTableInReferencingClause;	private boolean newTableInReferencingClause;	/**	 * Initializer for a CreateTriggerNode	 *	 * @param triggerName			name of the trigger		 * @param tableName				name of the table which the trigger is declared upon		 * @param triggerEventMask		TriggerDescriptor.TRIGGER_EVENT_XXX	 * @param triggerCols			columns trigger is to fire upon.  Valid	 *								for UPDATE case only.	 * @param isBefore				is before trigger (false for after)	 * @param isRow					true for row trigger, false for statement	 * @param isEnabled				true if enabled	 * @param refClause				the referencing clause	 * @param whenClause			the WHEN clause tree	 * @param whenText				the text of the WHEN clause	 * @param whenOffset			offset of start of WHEN clause	 * @param actionNode			the trigger action tree	 * @param actionText			the text of the trigger action	 * @param actionOffset			offset of start of action clause	 *	 * @return	A CreateTriggerNode 	 *	 * @exception StandardException		Thrown on error	 */	public void init 	(		Object		triggerName,		Object		tableName,		Object				triggerEventMask,		Object triggerCols,		Object			isBefore,		Object			isRow,		Object			isEnabled,		Object			refClause,		Object	whenClause,		Object			whenText,		Object				whenOffset,		Object	actionNode,		Object			actionText,		Object				actionOffset	) throws StandardException	{		initAndCheck(triggerName);		this.triggerName = (TableName) triggerName;		this.tableName = (TableName) tableName;		this.triggerEventMask = ((Integer) triggerEventMask).intValue();		this.triggerCols = (ResultColumnList) triggerCols;		this.isBefore = ((Boolean) isBefore).booleanValue();		this.isRow = ((Boolean) isRow).booleanValue();		this.isEnabled = ((Boolean) isEnabled).booleanValue();		this.refClause = (Vector) refClause;			this.whenClause = (QueryTreeNode) whenClause;		this.whenText = (whenText == null) ? null : ((String) whenText).trim();		this.whenOffset = ((Integer) whenOffset).intValue();		this.actionNode = (StatementNode) actionNode;		this.originalActionText = (String) actionText;		this.actionText =					(actionText == null) ? null : ((String) actionText).trim();		this.actionOffset = ((Integer) actionOffset).intValue();		implicitCreateSchema = true;	}	public String statementToString()	{		return "CREATE TRIGGER";	}	/**	 * Prints the sub-nodes of this object.  See QueryTreeNode.java for	 * how tree printing is supposed to work.	 *	 * @param depth		The depth of this node in the tree	 *	 * @return	Nothing	 */	public void printSubNodes(int depth)	{		if (SanityManager.DEBUG)		{			super.printSubNodes(depth);			if (triggerCols != null)			{				printLabel(depth, "triggerColumns: ");				triggerCols.treePrint(depth + 1);			}			if (whenClause != null)			{				printLabel(depth, "whenClause: ");				whenClause.treePrint(depth + 1);			}			if (actionNode != null)			{				printLabel(depth, "actionNode: ");				actionNode.treePrint(depth + 1);			}		}	}	// accessors	// We inherit the generate() method from DDLStatementNode.	/**	 * Bind this CreateTriggerNode.  This means doing any static error	 * checking that can be done before actually creating the table.	 *	 * @return	The bound query tree	 *	 * @exception StandardException		Thrown on error	 */	public QueryTreeNode bind() throws StandardException	{		CompilerContext compilerContext = getCompilerContext();		DataDictionary	dd = getDataDictionary();		/*		** Grab the current schema.  We will use that for		** sps compilation		*/		LanguageConnectionContext lcc = getLanguageConnectionContext();		compSchemaDescriptor = lcc.getDefaultSchema();		/*		** Get and check the schema descriptor for this		** trigger.  This check will throw the proper exception		** if someone tries to create a trigger in the SYS		** schema.		*/		triggerSchemaDescriptor = getSchemaDescriptor();		/*		** Get the trigger table.		*/		triggerTableDescriptor = getTableDescriptor(tableName);		//throw an exception if user is attempting to create a trigger on a temporary table		if (isSessionSchema(triggerTableDescriptor.getSchemaDescriptor()))		{				throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);		}		/*		** Regenerates the actionText and actionNode if necessary.		*/		boolean needInternalSQL = bindReferencesClause(dd);		lcc.pushTriggerTable(triggerTableDescriptor);		try		{				/*			** Bind the trigger action and the trigger			** when clause to make sure that they are			** ok.  Note that we have already substituted 			** in various replacements for OLD/NEW transition			** tables/variables and reparsed if necessary.			*/			if (needInternalSQL)				compilerContext.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);			actionNode.bind();			if (whenClause != null)			{				whenClause.bind();			}		}		finally		{			lcc.popTriggerTable(triggerTableDescriptor);		}		/* 		** Statement is dependent on the TableDescriptor 		*/		compilerContext.createDependency(triggerTableDescriptor);		/*		** If there is a list of columns, then no duplicate columns,		** and all columns must be found.		*/		if (triggerCols != null && triggerCols.size() != 0)		{			referencedColInts = new int[triggerCols.size()];			Hashtable columnNames = new Hashtable();			int tcSize = triggerCols.size();			for (int i = 0; i < tcSize; i++)			{				ResultColumn rc  = (ResultColumn) triggerCols.elementAt(i);				if (columnNames.put(rc.getName(), rc) != null)				{					throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_IN_TRIGGER_UPDATE, 											rc.getName(), 											triggerName);				}				ColumnDescriptor cd = triggerTableDescriptor.getColumnDescriptor(rc.getName());				if (cd == null)				{					throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, 																rc.getName(),																tableName);				}				referencedColInts[i] = cd.getPosition();			} 			// sort the list			java.util.Arrays.sort(referencedColInts);		}		//If attempting to reference a SESSION schema table (temporary or permanent) in the trigger action, throw an exception		if (actionNode.referencesSessionSchema())			throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);		return this;	}	/**	 * Return true if the node references SESSION schema tables (temporary or permanent)	 *	 * @return	true if references SESSION schema tables, else false	 *	 * @exception StandardException		Thrown on error	 */	public boolean referencesSessionSchema()		throws StandardException	{		//If create trigger is part of create statement and the trigger is defined on or it references SESSION schema tables,		//it will get caught in the bind phase of trigger and exception will be thrown by the trigger bind. 		return (isSessionSchema(triggerTableDescriptor.getSchemaName()) || actionNode.referencesSessionSchema());	}	/*	** BIND OLD/NEW TRANSITION TABLES/VARIABLES	**	** 1) validate the referencing clause (if any)	**	** 2) convert trigger action text.  e.g. 	**		DELETE FROM t WHERE c = old.c	** turns into	**		DELETE FROM t WHERE c = org.apache.derby.iapi.db.Factory::	**					getTriggerExecutionContext().getOldRow().getInt('C');	** or	**		DELETE FROM t WHERE c in (SELECT c FROM OLD)	** turns into	**		DELETE FROM t WHERE c in (SELECT c FROM new TriggerOldTransitionTable OLD)	**	** 3) check all column references against new/old transition 	**	variables (since they are no longer 'normal' column references	** 	that will be checked during bind)	**	** 4) reparse the new action text	**	** You might be wondering why we regenerate the text and reparse	** instead of just reworking the tree to have the nodes we want.	** Well, the primary reason is that if we screwed with the tree,	** then we would have a major headache if this trigger action	** was ever recompiled -- spses don't really know that they are	** triggers so it would be quite arduous to figure out that an	** sps is a trigger and munge up its query tree after figuring	** out what its OLD/NEW tables are, etc.  Also, it is just plain	** easier to just generate the sql and rebind.  	*/	private boolean bindReferencesClause(DataDictionary dd) throws StandardException	{		validateReferencesClause(dd);		StringBuffer newText = new StringBuffer();		boolean regenNode = false;		int start = 0;		if (isRow)		{			/*			** For a row trigger, we find all column references.  If			** they are referencing NEW or OLD we turn them into			** getTriggerExecutionContext().getOldRow().getInt('C');			*/			CollectNodesVisitor visitor = new CollectNodesVisitor(ColumnReference.class);			actionNode.accept(visitor);			Vector refs = visitor.getList();			/* we need to sort on position in string, beetle 4324			 */			QueryTreeNode[] cols = sortRefs(refs, true);			for (int i = 0; i < cols.length; i++)			{				ColumnReference ref = (ColumnReference) cols[i];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -