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

📄 castnode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 *	 * @exception StandardException			Thrown on error	 */	public ValueNode remapColumnReferencesToExpressions()		throws StandardException	{		castOperand = castOperand.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 castOperand.isConstantExpression();	}	/** @see ValueNode#constantExpression */	public boolean constantExpression(PredicateList whereClause)	{		return castOperand.constantExpression(whereClause);	}	/**	 * By default unary operators don't accept ? parameters as operands.	 * This can be over-ridden for particular unary operators.	 *	 * @return	Nothing	 *	 * @exception StandardException		Always thrown to indicate a	 *									? parameter where it isn't allowed.	 */	void bindParameter()					throws StandardException	{		((ParameterNode) castOperand).setDescriptor(castTarget);	}	/**	 * Return an Object representing the bind time value of this	 * expression tree.  If the expression tree does not evaluate to	 * a constant at bind time then we return null.	 * This is useful for bind time resolution of VTIs.	 * RESOLVE: What do we do for primitives?	 *	 * @return	An Object representing the bind time value of this expression tree.	 *			(null if not a bind time constant.)	 *	 * @exception StandardException		Thrown on error	 */	Object getConstantValueAsObject()		throws StandardException	{		Object sourceObject = castOperand.getConstantValueAsObject();		// RESOLVE - need to figure out how to handle casts		if (sourceObject == null)		{			return null;		}		// Simple if source and destination are of same type		if (sourceCTI.getCorrespondingJavaTypeName().equals(				destCTI.getCorrespondingJavaTypeName()))		{			return sourceObject;		}		// RESOLVE - simply return null until we can figure out how to 		// do the cast		return null;	}	/**	 * Do code generation for this unary operator.	 *	 * @param acb	The ExpressionClassBuilder for the class we're generating	 * @param mb	The method the code to place the code	 *	 * @return	An expression to evaluate this operator	 *	 * @exception StandardException		Thrown on error	 */	public void generateExpression(ExpressionClassBuilder acb,											MethodBuilder mb)									throws StandardException	{		castOperand.generateExpression(acb, mb);		/* No need to generate code for null constants */		if (castOperand instanceof UntypedNullConstantNode)		{			return;		}		/* HACK ALERT. When casting a parameter, there		 * is not sourceCTI.  Code generation requires one,		 * so we simply set it to be the same as the		 * destCTI.  The user can still pass whatever		 * type they'd like in as a parameter.		 * They'll get an exception, as expected, if the		 * conversion cannot be performed.		 */		else if (castOperand.isParameterNode())		{			sourceCTI = destCTI;		}			genDataValueConversion(acb, mb);	}	private void genDataValueConversion(ExpressionClassBuilder acb,											  MethodBuilder mb)			throws StandardException	{		MethodBuilder	acbConstructor = acb.getConstructor();		String resultTypeName = getTypeCompiler().interfaceName();		/* field = method call */		/* Allocate an object for re-use to hold the result of the operator */		LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);		/*		** Store the result of the method call in the field, so we can re-use		** the object.		*/		acb.generateNull(acbConstructor, getTypeCompiler(destCTI));		acbConstructor.setField(field);		/*			For most types generate			targetDVD.setValue(sourceDVD);			// optional for variable length types			targetDVD.setWidth();		*/		if (!sourceCTI.isNationalStringTypeId() && !sourceCTI.userType() && !destCTI.userType()) {		mb.getField(field); // targetDVD reference for the setValue method call		mb.swap();		mb.cast(ClassName.DataValueDescriptor);		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, "setValue", "void", 1);		mb.getField(field);		/* 		** If we are casting to a variable length datatype, we		** have to make sure we have set it to the correct		** length.		*/		if (destCTI.variableLength()) 		{			boolean isNumber = destCTI.isNumericTypeId();			/* setWidth() is on VSDV - upcast since			 * decimal implements subinterface			 * of VSDV.			 */			mb.push(isNumber ? castTarget.getPrecision() : castTarget.getMaximumWidth());			mb.push(castTarget.getScale());			mb.push(!sourceCTI.variableLength() || isNumber);			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", ClassName.DataValueDescriptor, 3);			/* setWidth returns DataValueDescriptor - we need 			 * to cast result to actual subinterface getting returned.			 */			mb.cast(resultTypeName);		}		return;		}		/*		** If we are casting from a national string to a date, time,		** or timestamp, do a getDate(), getTime(), or getTimestamp()		** rather than a getObject(). This is because getObject() returns		** a String, and setValue() can't tell whether the String comes		** from a national or non-national character type, so it can't tell		** whether to use the database locale to do the conversion.		*/		String getMethod = "getObject";		String getType = "java.lang.Object";		String castType = sourceCTI.getCorrespondingJavaTypeName();		int argCount = 0;		if (sourceCTI.isNationalStringTypeId())		{			switch (destCTI.getJDBCTypeId())			{			  case Types.DATE:				getMethod = "getDate";				getType = "java.sql.Date";				castType = getType;				break;			  case Types.TIME:				getMethod = "getTime";				getType = "java.sql.Time";				castType = getType;				break;			  case Types.TIMESTAMP:				getMethod = "getTimestamp";				getType = "java.sql.Timestamp";				castType = getType;				break;			}			if (!getMethod.equals("getObject")) {				mb.pushThis();				mb.callMethod(VMOpcode.INVOKEVIRTUAL, 					acb.getBaseClassName(), 					"getCalendar", "java.util.Calendar", 0);				argCount++;			}		}		/* 		** generate: field.setValue((<type>) expr.getObject ) 		** or		 field.setValue((<type>) expr.getDate )		** or		 field.setValue((<type>) expr.getTime )		** or		 field.setValue((<type>) expr.getTimestamp )		*/		mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, getMethod, getType, argCount);		/* 		** Cast to java.lang.Object if source or destination type 		** is a java type because that's how the interface is defined.		*/		mb.cast(destCTI.userType() || sourceCTI.userType() ? "java.lang.Object" : castType);		//castExpr		mb.getField(field); // instance for the setValue/setObjectForCast method call		mb.swap(); // push it before the value		/*		** If we are casting a java type, then		** we generate:		**		**		DataValueDescriptor.setObjectForCast(java.lang.Object castExpr, boolean instanceOfExpr, destinationClassName)		** where instanceOfExpr is "source instanceof destinationClass".		**		** otherwise:		**		**		<specificDataValue>.setValue(<type>castExpr)		*/		if (sourceCTI.userType())		{			String destinationType = getTypeId().getCorrespondingJavaTypeName();			// at this point method instance and cast result are on the stack			// we duplicate the cast value in order to perform the instanceof check			mb.dup();			mb.isInstanceOf(destinationType);			mb.push(destinationType);			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, "setObjectForCast", "void", 3);		}		else		{			String itype = ClassName.DataValueDescriptor;			if (castType.startsWith("java.lang.")) {				if (!castType.equals("java.lang.String") && !castType.equals("java.lang.Object"))					itype = resultTypeName;			}			// System.out.println("type = " + castType);			mb.callMethod(VMOpcode.INVOKEINTERFACE, itype, "setValue", "void", 1);			// mb.endStatement();		}		mb.getField(field);		/* 		** If we are casting to a variable length datatype, we		** have to make sure we have set it to the correct		** length.		*/		if (destCTI.variableLength()) 		{			boolean isNumber = destCTI.isNumericTypeId();			/* setWidth() is on VSDV - upcast since			 * decimal implements subinterface			 * of VSDV.			 */			mb.push(isNumber ? castTarget.getPrecision() : castTarget.getMaximumWidth());			mb.push(castTarget.getScale());			mb.push(!sourceCTI.variableLength() || isNumber);			mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", ClassName.DataValueDescriptor, 3);								/*								** The last argument is true if we should								** throw error on truncation.  We throw an								** error on all but Bits and Strings								** (everything with variable length that								** isn't a number -- all variable length								** except DECIMAL/NUMERIC).								*/								/* RESOLVE:								** NOTE: If the source is a parameter								** then the user can pass any type								** in as the parameter.  We will not								** raise a truncation exception in								** this case, even if we would if the								** cast was directly on the value								** being passed in as a parameter.								** For example:								**	cast(123 as char(1)) throws truncation								**			exception								**	cast(? as char(1)), user passes 123								**		no truncation exception								** We are considering this behavior to be								** an extension, at least for now. We may 								** need to revisit this if there's a								** SQL-J compliance test with this.								** (The solution would be to add a method								** off of ParameterValueSet to get some								** info about the data type of the								** actual parameter and generate code for								** the 3rd parameter to setWidth() based								** on the execution time data type.								*/			/* setWidth returns DataValueDescriptor - we need 			 * to cast result to actual subinterface getting returned.			 */			mb.cast(resultTypeName);		}		}	/**	 * 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 (castOperand != null && !v.stopTraversal())		{			castOperand = (ValueNode)castOperand.accept(v);		}		return returnNode;	}	/** set this to be a dataTypeScalarFunction	 * 	 * @param b true to use function conversion rules	 */	public void setForDataTypeFunction(boolean b)	{		forDataTypeFunction = b;	}	/** is this a cast node for a data type scalar function?	 * @return true if this is  a function, false for regular cast node	 *	 */	public boolean getForDataTypeFunction()	{		return forDataTypeFunction;	}}

⌨️ 快捷键说明

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