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

📄 likeescapeoperatornode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		if (rightOperand != null)		{			nullableResult |= rightOperand.getTypeServices().isNullable();		}		setType(new DataTypeDescriptor(						TypeId.BOOLEAN_ID,						nullableResult					)				);	}	/**	 * Bind this operator	 *	 * @return	Nothing	 *	 * @exception StandardException		Thrown on error	 */	public void bindComparisonOperator()			throws StandardException	{		TypeId	receiverType = receiver.getTypeId();		TypeId	leftType = leftOperand.getTypeId();		/*		** Check the type of the operands - this function is allowed only on		** string types.		*/		if ( ! receiverType.isStringTypeId())		{			throw StandardException.newException(SQLState.LANG_LIKE_BAD_TYPE, 												receiverType.getSQLTypeName());		}		if (! leftType.isStringTypeId())		{			throw StandardException.newException(SQLState.LANG_LIKE_BAD_TYPE, 												leftType.getSQLTypeName());		}		if (rightOperand != null && ! rightOperand.getTypeId().isStringTypeId())		{			throw StandardException.newException(SQLState.LANG_LIKE_BAD_TYPE, 												rightOperand.getTypeId().getSQLTypeName());		}	}	/**	 * 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	{		boolean eliminateLikeComparison = false;		String	greaterEqualString = null;		String  lessThanString = null;		String  pattern;		/* We must 1st preprocess the component parts */		super.preprocess(numTables,						 outerFromList, outerSubqueryList,						 outerPredicateList);        /* Don't try to optimize for (C)LOB type since it         * doesn't allow comparison.         */        if (receiver.getTypeId().getSQLTypeName().equals("CLOB")) {            return this;        }		/* No need to consider transformation if we		 * already did transformation that added =		 * at bind time.		 */		if (addedEquals)		{			return this;		}		/* This is where we do the transformation for LIKE to make it optimizable.		 * c1 LIKE 'asdf%' -> c1 LIKE 'asdf%' AND c1 >= 'asdf' AND c1 < 'asdg'		 * c1 LIKE ? -> c1 LIKE ? and c1 >= ?', where ?' gets calculated at the		 * beginning of execution.		 */		if (!(leftOperand instanceof CharConstantNode) &&			!(leftOperand.isParameterNode()))		{			return this;		}		/* This transformation is only worth doing if it is pushable, ie, if		 * the receiver is a ColumnReference.		 */		if (!(receiver instanceof ColumnReference))		{			//			// We also do an early return here if in bindExpression we found we had			// a National Char and put a CAST above the receiver.			//			return this;		}		// Build String constants if right side is a constant		if (leftOperand instanceof CharConstantNode)		{			pattern = ((CharConstantNode) leftOperand).getString();			if (! Like.isOptimizable(pattern))			{				return this;			}			int maxWidth = receiver.getTypeServices().getMaximumWidth();			greaterEqualString = Like.greaterEqualString(pattern, escape, 														 maxWidth);			/* We do not generate the < and we cannot drop the LIKE			 * when doing LIKE on a national char column.			 */            if ( ! receiver.getTypeId().isNationalStringTypeId() )			{				lessThanString = Like.lessThanString(pattern, escape, maxWidth);				eliminateLikeComparison = ! Like.isLikeComparisonNeeded(pattern);			}		}		//System.out.println(receiver.getTypeServices());		//System.out.println("MAX WIDTH " + receiver.getTypeServices().getMaximumWidth());		/* For some unknown reason we need to clone the receiver if it is		 * a ColumnReference because reusing them in Qualifiers for a scan		 * does not work.  		 */		/* The transformed tree has to be normalized.  Either:		 *			AND									AND		 *		   /   \							   /   \		 *	     LIKE   AND				OR:			 LIKE	AND		 *			   /   \							   /   \		 *			  >=    AND							  >=    TRUE		 *				   /   \		 *				  <     TRUE		 * unless the like string is of the form CONSTANT%, in which		 * case we can do away with the LIKE altogether:		 *			AND									AND		 *		   /   \							   /   \		 *	     >=     AND				OR:			 >=  	TRUE		 *			   /   \		 *			  <    TRUE		 */		AndNode	  newAnd = null;        ValueNode trueNode = (ValueNode) getNodeFactory().getNode(											C_NodeTypes.BOOLEAN_CONSTANT_NODE,											Boolean.TRUE,											getContextManager());		/* Create the AND <, if lessThanString is non-null  or 		 * leftOperand is a parameter.		   Currently for a national string we do not add a < than operator		   since we don't know (?) how to calculate such a string.		 */		if ( lessThanString != null || ( leftOperand.isParameterNode() &&                                         ! receiver.getTypeId().isNationalStringTypeId() ))		{			QueryTreeNode likeLTopt;			if (leftOperand.isParameterNode())			{				int maxWidth = receiver.getTypeServices().getMaximumWidth();				likeLTopt = setupOptimizeStringFromParameter(leftOperand, rightOperand,								"lessThanStringFromParameter", maxWidth);			}			else			{				likeLTopt = getNodeFactory().getNode(												C_NodeTypes.CHAR_CONSTANT_NODE,												lessThanString,												getContextManager());			}			BinaryComparisonOperatorNode lessThan = 					(BinaryComparisonOperatorNode) getNodeFactory().getNode(							C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE,							receiver.getClone(), 							likeLTopt,							getContextManager());			// Disable comparability checks			lessThan.setForQueryRewrite(true);			/* Set type info for the operator node */			lessThan.bindComparisonOperator();			// Use between selectivity for the <			lessThan.setBetweenSelectivity();			/* Create the AND */			newAnd = (AndNode) getNodeFactory().getNode(													C_NodeTypes.AND_NODE,													lessThan,													trueNode,													getContextManager());			newAnd.postBindFixup();		}		/* Create the AND >=.  Right side could		 * be a CharConstantNode or a ParameterNode.		 */		ValueNode likeGEopt;		if (leftOperand.isParameterNode()) {			// Create an expression off the parameter			// new SQLChar(Like.greaterEqualString(?));			int maxWidth = receiver.getTypeServices().getMaximumWidth();			likeGEopt = setupOptimizeStringFromParameter(leftOperand, rightOperand,								"greaterEqualStringFromParameter", maxWidth);		} else {			likeGEopt = (ValueNode) getNodeFactory().getNode(C_NodeTypes.CHAR_CONSTANT_NODE,												greaterEqualString,												getContextManager());		}		BinaryComparisonOperatorNode greaterEqual = 				(BinaryComparisonOperatorNode) getNodeFactory().getNode(						C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE,						receiver.getClone(), 						likeGEopt,						getContextManager());		// Disable comparability checks		greaterEqual.setForQueryRewrite(true);		/* Set type info for the operator node */		greaterEqual.bindComparisonOperator();		// Use between selectivity for the >=		greaterEqual.setBetweenSelectivity();		/* Create the AND */		if (newAnd == null)		{			newAnd = (AndNode) getNodeFactory().getNode(													C_NodeTypes.AND_NODE,													greaterEqual,													trueNode,													getContextManager());		}		else		{			newAnd = (AndNode) getNodeFactory().getNode(													C_NodeTypes.AND_NODE,													greaterEqual,													newAnd,													getContextManager());		}		newAnd.postBindFixup();		/* Finally, we put a AND LIKE on top of the left deep tree, but		 * only if it is still necessary.	     */		if (! eliminateLikeComparison)		{			newAnd = (AndNode) getNodeFactory().getNode(													C_NodeTypes.AND_NODE,													this,													newAnd,													getContextManager());			newAnd.postBindFixup();		}		/* Mark this node as transformed so that we don't get		 * calculated into the selectivity mulitple times.		 */		setTransformed();		return newAnd;	}	/**	 * Do code generation for this binary operator.	 *	 *		This code was copied from BinaryOperatorNode and stripped down	 *	 * @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	{/*** 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?*/		/*		** 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 = getReceiverInterfaceName();		/*		** Generate LHS (field = <receiver operand>). This assignment is		** used as the receiver of the method call for this operator.		**		**	(<receiver operand>).method(<left operand>,		**                      <right operand>, [<escaperightOp>,]		**						<result field>)		*/		receiver.generateExpression(acb, mb);	// first arg		receiverInterfaceType = receiver.getTypeCompiler().interfaceName();		mb.upCast(receiverInterfaceType); 		// cast the method instance		leftOperand.generateExpression(acb, mb);		mb.upCast(leftInterfaceType); 			// first arg with cast		if (rightOperand != null)		{			rightOperand.generateExpression(acb, mb);			mb.upCast(rightInterfaceType); 		// second arg with cast		}		/* Figure out the result type name */		// resultTypeName = getTypeCompiler().interfaceName();		mb.callMethod(VMOpcode.INVOKEINTERFACE, null,			methodName, resultInterfaceType,			rightOperand == null ? 1 : 2);	}	private ValueNode setupOptimizeStringFromParameter(ValueNode parameterNode,						ValueNode escapeNode,String methodName, int maxWidth)		throws StandardException {		Vector param;		if (escapeNode != null)		{			param = new Vector(2);			methodName += "WithEsc";		}		else param = new Vector(1);		StaticMethodCallNode methodCall = (StaticMethodCallNode)						getNodeFactory().getNode(C_NodeTypes.STATIC_METHOD_CALL_NODE,											methodName,											"org.apache.derby.iapi.types.Like",											getContextManager());		// using a method call directly, thus need internal sql capability		methodCall.internalCall = true;		param.addElement(parameterNode);		if (escapeNode != null)			param.addElement(escapeNode);		QueryTreeNode maxWidthNode = getNodeFactory().getNode(										C_NodeTypes.INT_CONSTANT_NODE,										new Integer(maxWidth),										getContextManager());		param.addElement(maxWidthNode);		methodCall.addParms(param);		ValueNode java2SQL = (ValueNode) getNodeFactory().getNode(									C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,									methodCall,									getContextManager());		java2SQL = (ValueNode) java2SQL.bindExpression(null, null, null);		CastNode likeOpt = (CastNode)			getNodeFactory().getNode(				C_NodeTypes.CAST_NODE,				java2SQL,				parameterNode.getTypeServices(),				getContextManager());		likeOpt.bindCastNodeOnly();		return likeOpt;	}}

⌨️ 快捷键说明

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