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

📄 createtriggernode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				TableName tableName = ref.getTableNameNode();				if ((tableName == null) ||					((oldTableName == null || !oldTableName.equals(tableName.getTableName())) &&					(newTableName == null || !newTableName.equals(tableName.getTableName()))))				{					continue;				}									int tokBeginOffset = tableName.getTokenBeginOffset();				int tokEndOffset = tableName.getTokenEndOffset();				if (tokBeginOffset == -1)				{					continue;				}				regenNode = true;				checkInvalidTriggerReference(tableName.getTableName());				String colName = ref.getColumnName();				int columnLength = ref.getTokenEndOffset() - ref.getTokenBeginOffset() + 1;				newText.append(originalActionText.substring(start, tokBeginOffset-actionOffset));				newText.append(genColumnReferenceSQL(dd, colName, tableName.getTableName(), tableName.getTableName().equals(oldTableName)));				start = tokEndOffset- actionOffset + columnLength + 2;			}		}		else		{			/*			** For a statement trigger, we find all FromBaseTable nodes.  If			** the from table is NEW or OLD (or user designated alternates			** REFERENCING), we turn them into a trigger table VTI.			*/			CollectNodesVisitor visitor = new CollectNodesVisitor(FromBaseTable.class);			actionNode.accept(visitor);			Vector refs = visitor.getList();			QueryTreeNode[] tabs = sortRefs(refs, false);			for (int i = 0; i < tabs.length; i++)			{				FromBaseTable fromTable = (FromBaseTable) tabs[i];				String refTableName = fromTable.getTableName().getTableName();				String baseTableName = fromTable.getBaseTableName();				if ((baseTableName == null) ||					((oldTableName == null || !oldTableName.equals(baseTableName)) &&					(newTableName == null || !newTableName.equals(baseTableName))))				{					continue;				}				int tokBeginOffset = fromTable.getTableNameField().getTokenBeginOffset();				int tokEndOffset = fromTable.getTableNameField().getTokenEndOffset();				if (tokBeginOffset == -1)				{					continue;				}				checkInvalidTriggerReference(baseTableName);				regenNode = true;				newText.append(originalActionText.substring(start, tokBeginOffset-actionOffset));				newText.append(baseTableName.equals(oldTableName) ?								"new org.apache.derby.catalog.TriggerOldTransitionRows() " :								"new org.apache.derby.catalog.TriggerNewTransitionRows() ");				/*				** If the user supplied a correlation, then just				** pick it up automatically; otherwise, supply				** the default.				*/				if (refTableName.equals(baseTableName))				{					newText.append(baseTableName).append(" ");				}				start=tokEndOffset-actionOffset+1;			}		}		/*		** Parse the new action text with the substitutions.		** Also, we reset the actionText to this new value.  This		** is what we are going to stick in the system tables.		*/		if (regenNode)		{			if (start < originalActionText.length())			{				newText.append(originalActionText.substring(start));			}			actionText = newText.toString();			actionNode = (StatementNode)reparseTriggerText(actionText);		}		return regenNode;	}	/*	** Sort the refs into array.	*/	private QueryTreeNode[] sortRefs(Vector refs, boolean isRow)	{		int size = refs.size();		QueryTreeNode[] sorted = new QueryTreeNode[size];		int i = 0;		for (Enumeration e = refs.elements(); e.hasMoreElements(); )		{			if (isRow)				sorted[i++] = (ColumnReference)e.nextElement();			else				sorted[i++] = (FromBaseTable)e.nextElement();		}		/* bubble sort		 */		QueryTreeNode temp;		for (i = 0; i < size - 1; i++)		{			temp = null;			for (int j = 0; j < size - i - 1; j++)			{				if ((isRow && 					 ((ColumnReference) sorted[j]).getTokenBeginOffset() > 					 ((ColumnReference) sorted[j+1]).getTokenBeginOffset()					) ||					(!isRow &&					 ((FromBaseTable) sorted[j]).getTableNameField().getTokenBeginOffset() > 					 ((FromBaseTable) sorted[j+1]).getTableNameField().getTokenBeginOffset()					))				{					temp = sorted[j];					sorted[j] = sorted[j+1];					sorted[j+1] = temp;				}			}			if (temp == null)		// sorted				break;		}		return sorted;	}	/*	** Parse the text and return the tree.	*/	private QueryTreeNode reparseTriggerText(String text) throws StandardException	{		/*		** Get a new compiler context, so the parsing of the text		** doesn't mess up anything in the current context 		*/		LanguageConnectionContext lcc = getLanguageConnectionContext();		CompilerContext newCC = lcc.pushCompilerContext();		newCC.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);		try		{			return QueryTreeNode.parseQueryText(newCC, text, (Object[])null, lcc);		}		finally		{			lcc.popCompilerContext(newCC);		}	}	/*	** Make sure the given column name is found in the trigger	** target table.  Generate the appropriate SQL to get it.	**	** @return a string that is used to get the column using	** getObject() on the desired result set and CAST it back	** to the proper type in the SQL domain. 	**	** @exception StandardException on invalid column name	*/	private String genColumnReferenceSQL	(		DataDictionary	dd, 		String			colName, 		String			tabName,		boolean			isOldTable	) throws StandardException	{		ColumnDescriptor colDesc = null;		if ((colDesc = triggerTableDescriptor.getColumnDescriptor(colName)) == null)		{			throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND, tabName+"."+colName);		}		/*		** Generate something like this:		**		** 		cast (org.apache.derby.iapi.db.Factory::		**			getTriggerExecutionContext().getNewRow().		**				getObject('<colName>') AS DECIMAL(6,2))		**		** The cast back to the SQL Domain may seem redundant		** but we need it to make the column reference appear		** EXACTLY like a regular column reference, so we need		** the object in the SQL Domain and we need to have the		** type information.  Thus a user should be able to do 		** something like		**		**		CREATE TRIGGER ... INSERT INTO T length(Column), ...		*/		StringBuffer methodCall = new StringBuffer();		methodCall.append("cast (org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().");		methodCall.append(isOldTable ? "getOldRow()" : "getNewRow()");		methodCall.append(".getObject('"+colName+"') AS ");		DataTypeDescriptor dts = colDesc.getType();		TypeId typeId = dts.getTypeId();		/*		** getSQLString() returns <typeName> 		** for user types, so call getSQLTypeName in that		** case.		*/		methodCall.append((typeId.systemBuiltIn() ? 					dts.getSQLstring() :					typeId.getSQLTypeName()) + ") ");		return methodCall.toString();	}	/*	** Check for illegal combinations here: insert & old or	** delete and new	*/	private void checkInvalidTriggerReference(String tableName) throws StandardException	{		if (tableName.equals(oldTableName) && 			(triggerEventMask & TriggerDescriptor.TRIGGER_EVENT_INSERT) == TriggerDescriptor.TRIGGER_EVENT_INSERT)		{			throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "INSERT", "new");		}		else if (tableName.equals(newTableName) && 			(triggerEventMask & TriggerDescriptor.TRIGGER_EVENT_DELETE) == TriggerDescriptor.TRIGGER_EVENT_DELETE)		{			throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "DELETE", "old");		}	}	/*	** Make sure that the referencing clause is legitimate.	** While we are at it we set the new/oldTableName to	** be whatever the user wants.	*/	private void validateReferencesClause(DataDictionary dd) throws StandardException	{		if ((refClause == null) || (refClause.size() == 0))		{			return;		}		for (Enumeration e = refClause.elements(); e.hasMoreElements(); )		{			TriggerReferencingStruct trn = (TriggerReferencingStruct)e.nextElement();			/*			** 1) Make sure that we don't try to refer			** to a table for a row trigger or a row for			** a table trigger.			*/			if (isRow && !trn.isRow)			{				throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "ROW", "row");			}			else if (!isRow && trn.isRow) 			{				throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "STATEMENT", "table");			}			/*			** 2) Make sure we have no dups			*/			if (trn.isNew)			{				if (newTableInReferencingClause) 				{					throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_CLAUSE_DUPS);				}				/*				** 3a) No NEW reference in delete trigger				*/				if ((triggerEventMask & TriggerDescriptor.TRIGGER_EVENT_DELETE) == TriggerDescriptor.TRIGGER_EVENT_DELETE)				{					throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "DELETE", "old");				}				newTableName = trn.identifier;				newTableInReferencingClause = true;			}			else			{				if (oldTableInReferencingClause)				{					throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_CLAUSE_DUPS);				}				/*				** 3b) No OLD reference in insert trigger				*/				if ((triggerEventMask & TriggerDescriptor.TRIGGER_EVENT_INSERT) == TriggerDescriptor.TRIGGER_EVENT_INSERT)				{					throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "INSERT", "new");				}				oldTableName = trn.identifier;				oldTableInReferencingClause = true;			}			/*			** 4) Additional restriction on BEFORE triggers			*/			if (this.isBefore && !trn.isRow) {			// OLD_TABLE and NEW_TABLE not allowed for BEFORE triggers.				throw StandardException.newException(SQLState.LANG_TRIGGER_BAD_REF_MISMATCH, "BEFORE", "row");			}		}	}					/**	 * Create the Constant information that will drive the guts of Execution.	 *	 * @exception StandardException		Thrown on failure	 */	public ConstantAction makeConstantAction() throws StandardException	{		String oldReferencingName = (oldTableInReferencingClause) ? oldTableName : null;		String newReferencingName = (newTableInReferencingClause) ? newTableName : null;		return	getGenericConstantActionFactory().getCreateTriggerConstantAction(											triggerSchemaDescriptor.getSchemaName(),											getRelativeName(),											triggerEventMask,											isBefore,											isRow,											isEnabled,											triggerTableDescriptor,												(UUID)null,			// when SPSID											whenText,											(UUID)null,			// action SPSid 											actionText,											(actionCompSchemaId == null) ?												compSchemaDescriptor.getUUID() :												actionCompSchemaId,											(Timestamp)null,	// creation time											referencedColInts,											originalActionText,											oldTableInReferencingClause,											newTableInReferencingClause,											oldReferencingName,											newReferencingName											);	}	/**	 * Convert this object to a String.  See comments in QueryTreeNode.java	 * for how this should be done for tree printing.	 *	 * @return	This object as a String	 */	public String toString()	{		if (SanityManager.DEBUG)		{			String refString = "null";			if (refClause != null)			{				StringBuffer buf = new StringBuffer();				for (Enumeration e = refClause.elements(); e.hasMoreElements(); )				{					buf.append("\t");					TriggerReferencingStruct trn = 								(TriggerReferencingStruct)e.nextElement();					buf.append(trn.toString());					buf.append("\n");				}				refString = buf.toString();			}			return super.toString() +				"tableName: "+tableName+						"\ntriggerEventMask: "+triggerEventMask+						"\nisBefore: "+isBefore+						"\nisRow: "+isRow+						"\nisEnabled: "+isEnabled+						"\nwhenText: "+whenText+				"\nrefClause: "+refString+				"\nactionText: "+actionText+				"\n";		}		else		{			return "";		}	}}

⌨️ 快捷键说明

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