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

📄 staticmethodcallnode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
								// if it's not an exact length match then some cast will be needed.								if (!paramdtd.isExactTypeAndLengthMatch(dts))									needCast = true;							}						}						else						{							// any variable length type will need a cast from the							// Java world (the ? parameter) to the SQL type. This							// ensures values like CHAR(10) are passed into the procedure							// correctly as 10 characters long.							if (parameterTypeId.variableLength()) {								if (parameterMode != JDBC30Translation.PARAMETER_MODE_OUT)									needCast = true;							}						}												if (needCast)						{							// push a cast node to ensure the							// correct type is passed to the method							// this gets tacky because before we knew							// it was a procedure call we ensured all the							// parameter are JavaNodeTypes. Now we need to							// push them back to the SQL domain, cast them							// and then push them back to the Java domain.							if (sqlParamNode == null) {								sqlParamNode = (ValueNode) getNodeFactory().getNode(									C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,									methodParms[p], 									getContextManager());							}							ValueNode castNode = (ValueNode) getNodeFactory().getNode(								C_NodeTypes.CAST_NODE,								sqlParamNode, 								paramdtd,								getContextManager());							methodParms[p] = (JavaValueNode) getNodeFactory().getNode(									C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,									castNode, 									getContextManager());							methodParms[p] = methodParms[p].bindExpression(fromList, subqueryList, aggregateVector);						}						// only force the type for a ? so that the correct type shows up						// in parameter meta data						if (isParameterMarker)							sqlParamNode.setDescriptor(paramdtd);					}					if (sigParameterCount != parameterCount) {						TypeId typeId = TypeId.getUserDefinedTypeId("java.sql.ResultSet[]", false);						DataTypeDescriptor dtd = new DataTypeDescriptor(								typeId,								0,								0,								false,								-1							);						signature[parameterCount] = new JSQLType(dtd);					}					this.routineInfo = routineInfo;					ad = proc;					// If a procedure is in the system schema and defined as executing					// SQL do we set we are in system code.					if (sd.isSystemSchema() && (routineInfo.getReturnType() == null) && routineInfo.getSQLAllowed() != RoutineAliasInfo.NO_SQL)						isSystemCode = true;					break;				}			}				}			/* Throw exception if no alias found */			if (ad == null)			{				Object errName;				if (procedureName == null)					errName = methodName;				else					errName = procedureName;				throw StandardException.newException(SQLState.LANG_NO_SUCH_METHOD_ALIAS, errName);			}				/* Query is dependent on the AliasDescriptor */			cc.createDependency(ad);			methodName = ad.getAliasInfo().getMethodName();			javaClassName = ad.getJavaClassName();		}		javaClassName = verifyClassExist(javaClassName, true);		/* Resolve the method call */		resolveMethodCall(javaClassName, true);		alreadyBound = true;		// If this is a function call with a variable length		// return type, then we need to push a CAST node.		if (routineInfo != null)		{			TypeDescriptor returnType = routineInfo.getReturnType();			if (returnType != null)			{				TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());				if (returnTypeId.variableLength()) {					// Cast the return using a cast node, but have to go					// into the SQL domain, and back to the Java domain.					DataTypeDescriptor returnValueDtd = new DataTypeDescriptor(								returnTypeId,								returnType.getPrecision(),								returnType.getScale(),								returnType.isNullable(),								returnType.getMaximumWidth()							);					ValueNode returnValueToSQL = (ValueNode) getNodeFactory().getNode(								C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,								this, 								getContextManager());					ValueNode returnValueCastNode = (ValueNode) getNodeFactory().getNode(									C_NodeTypes.CAST_NODE,									returnValueToSQL, 									returnValueDtd,									getContextManager());					JavaValueNode returnValueToJava = (JavaValueNode) getNodeFactory().getNode(										C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,										returnValueCastNode, 										getContextManager());					return returnValueToJava.bindExpression(fromList, subqueryList, aggregateVector);				}			}		}		return this;	}	/**		Push extra code to generate the casts within the		arrays for the parameters passed as arrays.	*/	public	void generateOneParameter(ExpressionClassBuilder acb,											MethodBuilder mb,											int parameterNumber )			throws StandardException	{		int parameterMode;		SQLToJavaValueNode sql2j = null;		if (methodParms[parameterNumber] instanceof SQLToJavaValueNode)			sql2j = (SQLToJavaValueNode) methodParms[parameterNumber];				if (routineInfo != null) {			parameterMode = routineInfo.getParameterModes()[parameterNumber];		} else {			// for a static method call the parameter always starts out as a in parameter, but			// may be registered as an IN OUT parameter. For a static method argument to be			// a dynmaically registered out parameter it must be a simple ? parameter			parameterMode = JDBC30Translation.PARAMETER_MODE_IN;			if (sql2j != null) {				if (sql2j.getSQLValueNode().isParameterNode()) {					// applicationParameterNumbers is only set up for a procedure.					int applicationParameterNumber = ((ParameterNode) (sql2j.getSQLValueNode())).getParameterNumber();					String parameterType = methodParameterTypes[parameterNumber];					if (parameterType.endsWith("[]")) {						// constructor  - setting up correct paramter type info						MethodBuilder constructor = acb.getConstructor();						acb.pushThisAsActivation(constructor);						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,											"getParameterValueSet", ClassName.ParameterValueSet, 0);						constructor.push(applicationParameterNumber);						constructor.push(JDBC30Translation.PARAMETER_MODE_UNKNOWN);						constructor.callMethod(VMOpcode.INVOKEINTERFACE, null,											"setParameterMode", "void", 2);						constructor.endStatement();					}				}			} 		}		switch (parameterMode) {		case JDBC30Translation.PARAMETER_MODE_IN:		case JDBC30Translation.PARAMETER_MODE_IN_OUT:		case JDBC30Translation.PARAMETER_MODE_UNKNOWN:			if (sql2j != null)				sql2j.returnsNullOnNullState = returnsNullOnNullState;			super.generateOneParameter(acb, mb, parameterNumber);			break;		case JDBC30Translation.PARAMETER_MODE_OUT:			// For an OUT parameter we require nothing to be pushed into the			// method call from the parameter node.			break;		}		switch (parameterMode) {		case JDBC30Translation.PARAMETER_MODE_IN:		case JDBC30Translation.PARAMETER_MODE_UNKNOWN:			break;		case JDBC30Translation.PARAMETER_MODE_IN_OUT:		case JDBC30Translation.PARAMETER_MODE_OUT:		{			// Create the array used to pass into the method. We create a			// new array for each call as there is a small chance the			// application could retain a reference to it and corrupt			// future calls with the same CallableStatement object.			String methodParameterType = methodParameterTypes[parameterNumber];			String arrayType = methodParameterType.substring(0, methodParameterType.length() - 2);			LocalField lf = acb.newFieldDeclaration(Modifier.PRIVATE, methodParameterType);			if (outParamArrays == null)				outParamArrays = new LocalField[methodParms.length];			outParamArrays[parameterNumber] = lf;			mb.pushNewArray(arrayType, 1);			mb.putField(lf);			// set the IN part of the parameter into the INOUT parameter.			if (parameterMode != JDBC30Translation.PARAMETER_MODE_OUT) {				mb.swap();				mb.setArrayElement(0);				mb.getField(lf);			}			break;			}		}	}	/**	 * 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	{		/* We stop here when only considering simple predicates		 *  as we don't consider method calls when looking		 * for null invariant predicates.		 */		if (simplePredsOnly)		{			return false;		}		boolean pushable = true;		pushable = pushable && super.categorize(referencedTabs, simplePredsOnly);		return pushable;	}	/**	 * 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)		{			return "javaClassName: " +				(javaClassName != null ? javaClassName : "null") + "\n" +				super.toString();		}		else		{			return "";		}	}	/**	 * Do code generation for this method call	 *	 * @param acb	The ExpressionClassBuilder for the class we're generating

⌨️ 快捷键说明

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