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

📄 binaryoperatornode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 */	public ValueNode genSQLJavaSQLTree() throws StandardException	{		TypeId leftTypeId = leftOperand.getTypeId();				if (!(leftTypeId.systemBuiltIn()))			leftOperand = leftOperand.genSQLJavaSQLTree();		TypeId rightTypeId = rightOperand.getTypeId();		if (!(rightTypeId.systemBuiltIn()))			rightOperand = rightOperand.genSQLJavaSQLTree();		return this;	}	/**	 * Preprocess an expression tree.  We do a number of transformations	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus	 * subquery flattening.	 * NOTE: This is done before the outer ResultSetNode is preprocessed.	 *	 * @param	numTables			Number of tables in the DML Statement	 * @param	outerFromList		FromList from outer query block	 * @param	outerSubqueryList	SubqueryList from outer query block	 * @param	outerPredicateList	PredicateList from outer query block	 *	 * @return		The modified expression	 *	 * @exception StandardException		Thrown on error	 */	public ValueNode preprocess(int numTables,								FromList outerFromList,								SubqueryList outerSubqueryList,								PredicateList outerPredicateList) 					throws StandardException	{		leftOperand = leftOperand.preprocess(numTables,											 outerFromList, outerSubqueryList,											 outerPredicateList);		rightOperand = rightOperand.preprocess(numTables,											   outerFromList, outerSubqueryList,											   outerPredicateList);		return this;	}	/**	 * Do code generation for this binary operator.	 *	 * @param acb	The ExpressionClassBuilder for the class we're generating	 * @param mb	The method the code to place the code	 *	 *	 * @exception StandardException		Thrown on error	 */	public void generateExpression(ExpressionClassBuilder acb,											MethodBuilder mb)		throws StandardException	{		String		resultTypeName;		String		receiverType;/*** if i have a operator.getOrderableType() == constant, then just cache ** it in a field.  if i have QUERY_INVARIANT, then it would be good to** cache it in something that is initialized each execution,** but how?*/		/*		** The receiver is the operand with the higher type precedence.		** Like always makes the left the receiver.		**		*/		if (leftOperand.getTypeId().typePrecedence() >			rightOperand.getTypeId().typePrecedence())		{			receiver = leftOperand;			/*			** let the receiver type be determined by an			** overridable method so that if methods are			** not implemented on the lowest interface of			** a class, they can note that in the implementation			** of the node that uses the method.			*/		    receiverType = (operatorType == -1)				? getReceiverInterfaceName()				: leftInterfaceType;			/*			** Generate (with <left expression> only being evaluated once)			**			**	<left expression>.method(<left expression>, <right expression>...)			*/			leftOperand.generateExpression(acb, mb);			mb.cast(receiverType); // cast the method instance			// stack: left						mb.dup();			mb.cast(leftInterfaceType);			// stack: left, left						rightOperand.generateExpression(acb, mb);			mb.cast(rightInterfaceType); // second arg with cast			// stack: left, left, right		}		else		{			receiver = rightOperand;			/*			** let the receiver type be determined by an			** overridable method so that if methods are			** not implemented on the lowest interface of			** a class, they can note that in the implementation			** of the node that uses the method.			*/		    receiverType = (operatorType == -1)				? getReceiverInterfaceName()				: rightInterfaceType;			/*			** Generate (with <right expression> only being evaluated once)			**			**	<right expression>.method(<left expression>, <right expression>)			*/			rightOperand.generateExpression(acb, mb);						mb.cast(receiverType); // cast the method instance			// stack: right						mb.dup();			mb.cast(rightInterfaceType);			// stack: right,right						leftOperand.generateExpression(acb, mb);			mb.cast(leftInterfaceType); // second arg with cast			// stack: right,right,left						mb.swap();			// stack: right,left,right					}		/* Figure out the result type name */		resultTypeName = (operatorType == -1)			? getTypeCompiler().interfaceName()			: resultInterfaceType;		// Boolean return types don't need a result field		boolean needField = !getTypeId().isBooleanTypeId();		if (needField) {			/* Allocate an object for re-use to hold the result of the operator */			LocalField resultField =				acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);			/*			** Call the method for this operator.			*/			mb.getField(resultField); // third arg			//following method is special code for concatenation where if field is null, we want it to be initialized to NULL SQLxxx type object			//before generating code "field = method(p1, p2, field);"			initializeResultField(acb, mb, resultField);			/* pass statically calculated scale to decimal divide method to make			 * result set scale consistent, beetle 3901			 */			int jdbcType;			if ((dataTypeServices != null) &&				((jdbcType = dataTypeServices.getJDBCTypeId()) == java.sql.Types.DECIMAL ||				 jdbcType == java.sql.Types.NUMERIC) &&				operator.equals("/"))			{				mb.push(dataTypeServices.getScale());		// 4th arg				mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 4);			}			else				mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 3);			//the need for following if was realized while fixing bug 5704 where decimal*decimal was resulting an overflow value but we were not detecting it			if (getTypeId().variableLength())//since result type is numeric variable length, generate setWidth code.			{				if (getTypeId().isNumericTypeId())				{					mb.push(getTypeServices().getPrecision());					mb.push(getTypeServices().getScale());					mb.push(true);					mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", ClassName.DataValueDescriptor, 3);					mb.cast(resultTypeName);				}			}			/*			** Store the result of the method call in the field, so we can re-use			** the object.			*/			mb.putField(resultField);		} else {			mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 2);		}	}	//following method is no-op here but in concatenation node, this method is used to check if resultField is null,	//and if yes, then we want it to be initialized to NULL SQLxxx type object	protected void initializeResultField(ExpressionClassBuilder acb, MethodBuilder mb, LocalField resultField)	{	}	/**	 * Set the leftOperand to the specified ValueNode	 *	 * @param newLeftOperand	The new leftOperand	 *	 * @return None.	 */	public void setLeftOperand(ValueNode newLeftOperand)	{		leftOperand = newLeftOperand;	}	/**	 * Get the leftOperand	 *	 * @return The current leftOperand.	 */	public ValueNode getLeftOperand()	{		return leftOperand;	}	/**	 * Set the rightOperand to the specified ValueNode	 *	 * @param newRightOperand	The new rightOperand	 *	 * @return None.	 */	public void setRightOperand(ValueNode newRightOperand)	{		rightOperand = newRightOperand;	}	/**	 * Get the rightOperand	 *	 * @return The current rightOperand.	 */	public ValueNode getRightOperand()	{		return rightOperand;	}	/**	 * Categorize this predicate.  Initially, this means	 * building a bit map of the referenced tables for each predicate.	 * If the source of this ColumnReference (at the next underlying level) 	 * is not a ColumnReference or a VirtualColumnNode then this predicate	 * will not be pushed down.	 *	 * For example, in:	 *		select * from (select 1 from s) a (x) where x = 1	 * we will not push down x = 1.	 * NOTE: It would be easy to handle the case of a constant, but if the	 * inner SELECT returns an arbitrary expression, then we would have to copy	 * that tree into the pushed predicate, and that tree could contain	 * subqueries and method calls.	 * RESOLVE - revisit this issue once we have views.	 *	 * @param referencedTabs	JBitSet with bit map of referenced FromTables	 * @param simplePredsOnly	Whether or not to consider method	 *							calls, field references and conditional nodes	 *							when building bit map	 *	 * @return boolean		Whether or not source.expression is a ColumnReference	 *						or a VirtualColumnNode.	 * @exception StandardException			Thrown on error	 */	public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)		throws StandardException	{		boolean pushable;		pushable = leftOperand.categorize(referencedTabs, simplePredsOnly);		pushable = (rightOperand.categorize(referencedTabs, simplePredsOnly) && pushable);		return pushable;	}	/**	 * Remap all ColumnReferences in this tree to be clones of the	 * underlying expression.	 *	 * @return ValueNode			The remapped expression tree.	 *	 * @exception StandardException			Thrown on error	 */	public ValueNode remapColumnReferencesToExpressions()		throws StandardException	{		leftOperand = leftOperand.remapColumnReferencesToExpressions();		rightOperand = rightOperand.remapColumnReferencesToExpressions();		return this;	}	/**	 * Return whether or not this expression tree represents a constant expression.	 *	 * @return	Whether or not this expression tree represents a constant expression.	 */	public boolean isConstantExpression()	{		return (leftOperand.isConstantExpression() &&				rightOperand.isConstantExpression());	}	/** @see ValueNode#constantExpression */	public boolean constantExpression(PredicateList whereClause)	{		return (leftOperand.constantExpression(whereClause) &&				rightOperand.constantExpression(whereClause));	}	/**	 * Determine the type the binary method is called on.	 * By default, based on the receiver.	 *	 * Override in nodes that use methods on super-interfaces of	 * the receiver's interface, such as comparisons.	 *	 * @exception StandardException		Thrown on error	 */	public String getReceiverInterfaceName() throws StandardException {		if (SanityManager.DEBUG)		{			SanityManager.ASSERT(receiver!=null,"can't get receiver interface name until receiver is set");		}		return receiver.getTypeCompiler().interfaceName();	}	/**	 * Return the variant type for the underlying expression.	 * The variant type can be:	 *		VARIANT				- variant within a scan	 *							  (method calls and non-static field access)	 *		SCAN_INVARIANT		- invariant within a scan	 *							  (column references from outer tables)	 *		QUERY_INVARIANT		- invariant within the life of a query	 *		CONSTANT			- immutable	 *	 * @return	The variant type for the underlying expression.	 * @exception StandardException	thrown on error	 */	protected int getOrderableVariantType() throws StandardException	{		int leftType = leftOperand.getOrderableVariantType();		int rightType = rightOperand.getOrderableVariantType();		return Math.min(leftType, rightType);	}	/**	 * Swap the left and right sides.	 *	 * @return Nothing.	 */	void swapOperands()	{		String	  tmpInterfaceType = leftInterfaceType;		ValueNode tmpVN = leftOperand;		leftOperand = rightOperand;		rightOperand = tmpVN;		leftInterfaceType = rightInterfaceType;		rightInterfaceType = tmpInterfaceType;	}	/**	 * Accept a visitor, and call v.visit()	 * on child nodes as necessary.  	 * 	 * @param v the visitor	 *	 * @exception StandardException on error	 */	public Visitable accept(Visitor v) 		throws StandardException	{		Visitable returnNode = v.visit(this);			if (v.skipChildren(this))		{			return returnNode;		}		if (leftOperand != null && !v.stopTraversal())		{			leftOperand = (ValueNode)leftOperand.accept(v);		}		if (rightOperand != null && !v.stopTraversal())		{			rightOperand = (ValueNode)rightOperand.accept(v);		}				return returnNode;	}}

⌨️ 快捷键说明

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