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

📄 inlistoperatornode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			leftClone = (leftOperand instanceof ColumnReference) ? leftOperand.getClone() : leftOperand;			rightBCO = (BinaryComparisonOperatorNode) 						getNodeFactory().getNode(							C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE,							leftClone,							(ValueNode) rightOperandList.elementAt(elemsDone),							getContextManager());			/* Set type info for the operator node */			rightBCO.bindComparisonOperator();			/* Create the AND */			newAnd = (AndNode) getNodeFactory().getNode(												C_NodeTypes.AND_NODE,												leftSide,												rightBCO,												getContextManager());			newAnd.postBindFixup();			leftSide = newAnd;		}		return leftSide;	}	/**	 * See if this IN list operator is referencing the same table.	 *	 * @param cr	The column reference.	 *	 * @return	true if in list references the same table as in cr.	 *	 * @exception StandardException		Thrown on error	 */	public boolean selfReference(ColumnReference cr)		throws StandardException	{		int size = rightOperandList.size();		for (int i = 0; i < size; i++)		{			ValueNode vn = (ValueNode) rightOperandList.elementAt(i);			if (vn.getTablesReferenced().get(cr.getTableNumber()))				return true;		}		return false;	}	/**	 * The selectivity for an "IN" predicate is generally very small.	 * This is an estimate applicable when in list are not all constants.	 */	public double selectivity(Optimizable optTable)	{		return 0.3d;	} 	/**	 * Do code generation for this IN list operator.	 *	 * @param acb	The ExpressionClassBuilder for the class we're generating	 * @param mb The MethodBuilder the expression will go into	 *	 * @return	An Expression to evaluate this operator	 *	 * @exception StandardException		Thrown on error	 */	public void generateExpression(ExpressionClassBuilder acb,											MethodBuilder mb)									throws StandardException	{		int			listSize = rightOperandList.size();		String		resultTypeName;		String		receiverType = ClassName.DataValueDescriptor;			String		leftInterfaceType = ClassName.DataValueDescriptor;		String		rightInterfaceType = ClassName.DataValueDescriptor + "[]";		if (SanityManager.DEBUG)		{			SanityManager.ASSERT(listSize > 0,				"listSize is expected to be > 0");		}		/*		** There are 2 parts to the code generation for an IN list -		** the code in the constructor and the code for the expression evaluation.		** The code that gets generated for the constructor is:		**		DataValueDescriptor[] field = new DataValueDescriptor[size];		**	For each element in the IN list that is a constant, we also generate:		**		field[i] = rightOperandList[i];		**			** If the IN list is composed entirely of constants, then we generate the		** the following:		**		leftOperand.in(rightOperandList, leftOperand, isNullable(), ordered, result);		**		** Otherwise, we create a new method.  This method contains the 		** assignment of the non-constant elements into the array and the call to the in()		** method, which is in the new method's return statement.  We then return a call		** to the new method.		*/		receiver = leftOperand;		/* Figure out the result type name */		resultTypeName = getTypeCompiler().interfaceName();		// Generate the code to build the array		LocalField arrayField =			acb.newFieldDeclaration(Modifier.PRIVATE, rightInterfaceType);		/* The array gets created in the constructor.		 * All constant elements in the array are initialized		 * in the constructor.  All non-constant elements, if any,		 * are initialized each time the IN list is evaluated.		 */		/* Assign the initializer to the DataValueDescriptor[] field */		MethodBuilder cb = acb.getConstructor();		cb.pushNewArray(ClassName.DataValueDescriptor, listSize);		cb.setField(arrayField);		/* Set the array elements that are constant */		int numConstants = 0;		MethodBuilder nonConstantMethod = null;		MethodBuilder currentConstMethod = cb;		for (int index = 0; index < listSize; index++)		{			MethodBuilder setArrayMethod;				if (rightOperandList.elementAt(index) instanceof ConstantNode)			{				numConstants++;						/*if too many statements are added  to a  method, 				*size of method can hit  65k limit, which will				*lead to the class format errors at load time.				*To avoid this problem, when number of statements added 				*to a method is > 2048, remaing statements are added to  a new function				*and called from the function which created the function.				*See Beetle 5135 or 4293 for further details on this type of problem.				*/				if(currentConstMethod.statementNumHitLimit(1))				{					MethodBuilder genConstantMethod = acb.newGeneratedFun("void", Modifier.PRIVATE);					currentConstMethod.pushThis();					currentConstMethod.callMethod(VMOpcode.INVOKEVIRTUAL,												  (String) null, 												  genConstantMethod.getName(),												  "void", 0);					//if it is a generate function, close the metod.					if(currentConstMethod != cb){						currentConstMethod.methodReturn();						currentConstMethod.complete();					}					currentConstMethod = genConstantMethod;				}				setArrayMethod = currentConstMethod;			} else {				if (nonConstantMethod == null)					nonConstantMethod = acb.newGeneratedFun("void", Modifier.PROTECTED);				setArrayMethod = nonConstantMethod;			}			setArrayMethod.getField(arrayField); // first arg			((ValueNode) rightOperandList.elementAt(index)).generateExpression(acb, setArrayMethod);			setArrayMethod.upCast(receiverType); // second arg			setArrayMethod.setArrayElement(index);		}		//if a generated function was created to reduce the size of the methods close the functions.		if(currentConstMethod != cb){			currentConstMethod.methodReturn();			currentConstMethod.complete();		}		if (nonConstantMethod != null) {			nonConstantMethod.methodReturn();			nonConstantMethod.complete();			mb.pushThis();			mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, nonConstantMethod.getName(), "void", 0);		}		/*		** Call the method for this operator.		*/		/*		** Generate (field = <left expression>).  This assignment is		** used as the receiver of the method call for this operator,		** and the field is used as the left operand:		**		**	(field = <left expression>).method(field, <right expression>...)		*/		//LocalField receiverField =		//	acb.newFieldDeclaration(Modifier.PRIVATE, receiverType);		leftOperand.generateExpression(acb, mb);		mb.dup();		//mb.putField(receiverField); // instance for method call		/*mb.getField(receiverField);*/ mb.upCast(leftInterfaceType); // first arg		mb.getField(arrayField); // second arg		mb.push(isOrdered); // third arg		mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, methodName, resultTypeName, 3);	}	/**	 * Generate start/stop key for this IN list operator.  Bug 3858.	 *	 * @param isAsc		is the index ascending on the column in question	 * @param isStartKey	are we generating start key or not	 * @param acb	The ExpressionClassBuilder for the class we're generating	 * @param mb The MethodBuilder the expression will go into	 *	 * @return	nothing	 *	 * @exception StandardException		Thrown on error	 */	public void generateStartStopKey(boolean isAsc, boolean isStartKey,									 ExpressionClassBuilder acb,									 MethodBuilder mb)											   throws StandardException	{		/* left side of the "in" operator is our "judge" when we try to get		 * the min/max value of the operands on the right side.  Judge's type		 * is important for us, and is input parameter to min/maxValue.		 */		int leftTypeFormatId = leftOperand.getTypeId().getTypeFormatId();		int leftJDBCTypeId = leftOperand.getTypeId().isUserDefinedTypeId() ?								leftOperand.getTypeId().getJDBCTypeId() : -1;		int listSize = rightOperandList.size();		int numLoops, numValInLastLoop, currentOpnd = 0;		/* We first calculate how many times (loops) we generate a call to		 * min/maxValue function accumulatively, since each time it at most		 * takes 4 input values.  An example of the calls generated will be:		 * minVal(minVal(...minVal(minVal(v1,v2,v3,v4,judge), v5,v6,v7,judge),		 *        ...), vn-1, vn, NULL, judge)		 * Unused value parameters in the last call are filled with NULLs.		 */		if (listSize < 5)		{			numLoops = 1;			numValInLastLoop = (listSize - 1) % 4 + 1;		}		else		{			numLoops = (listSize - 5) / 3 + 2;			numValInLastLoop = (listSize - 5) % 3 + 1;		}		for (int i = 0; i < numLoops; i++)		{			/* generate value parameters of min/maxValue			 */			int numVals = (i == numLoops - 1) ? numValInLastLoop :							  ((i == 0) ? 4 : 3);			for (int j = 0; j < numVals; j++)			{				ValueNode vn = (ValueNode) rightOperandList.elementAt(currentOpnd++);				vn.generateExpression(acb, mb);				mb.upCast(ClassName.DataValueDescriptor);			}			/* since we have fixed number of input values (4), unused ones			 * in the last loop are filled with NULLs			 */			int numNulls = (i < numLoops - 1) ? 0 :							((i == 0) ? 4 - numValInLastLoop : 3 - numValInLastLoop);			for (int j = 0; j < numNulls; j++)				mb.pushNull(ClassName.DataValueDescriptor);			/* have to put judge's types in the end			 */			mb.push(leftTypeFormatId);			mb.push(leftJDBCTypeId);			/* decide to get min or max value			 */			String methodName;			if ((isAsc && isStartKey) || (! isAsc && ! isStartKey))				methodName = "minValue";			else				methodName = "maxValue";					mb.callMethod(VMOpcode.INVOKESTATIC, ClassName.BaseExpressionActivation, methodName, ClassName.DataValueDescriptor, 6);		}	}}

⌨️ 快捷键说明

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