Search in sources :

Example 1 with TypeDescriptorImpl

use of org.apache.derby.catalog.types.TypeDescriptorImpl in project derby by apache.

the class DataTypeDescriptor method getType.

/**
 * Return a runtime type for a catalog type.
 */
public static DataTypeDescriptor getType(TypeDescriptor catalogType) {
    TypeDescriptorImpl typeDescriptor = (TypeDescriptorImpl) catalogType;
    TypeId typeId = TypeId.getTypeId(catalogType);
    DataTypeDescriptor dtd = new DataTypeDescriptor(typeDescriptor, typeId);
    // By definition, any catalog type (column in a table,
    // procedure etc.) is derivation implicit.
    dtd.collationDerivation = StringDataValue.COLLATION_DERIVATION_IMPLICIT;
    return dtd;
}
Also used : TypeDescriptorImpl(org.apache.derby.catalog.types.TypeDescriptorImpl)

Example 2 with TypeDescriptorImpl

use of org.apache.derby.catalog.types.TypeDescriptorImpl in project derby by apache.

the class TypeId method getTypeId.

/**
 * Get the TypeId (fundemental type information)
 * for a catalog type.
 * @param catalogType
 * @return TypeId that represents the base type, null if not applicable.
 */
public static TypeId getTypeId(TypeDescriptor catalogType) {
    TypeDescriptorImpl tdi = (TypeDescriptorImpl) catalogType;
    final int jdbcType = catalogType.getJDBCTypeId();
    TypeId typeId = TypeId.getBuiltInTypeId(jdbcType);
    if (typeId != null)
        return typeId;
    if (jdbcType == Types.JAVA_OBJECT) {
        return new TypeId(StoredFormatIds.USERDEFINED_TYPE_ID_V3, tdi.getTypeId());
    }
    if (tdi.isRowMultiSet()) {
        return new TypeId(StoredFormatIds.ROW_MULTISET_TYPE_ID_IMPL, tdi.getTypeId());
    }
    return null;
}
Also used : TypeDescriptorImpl(org.apache.derby.catalog.types.TypeDescriptorImpl)

Example 3 with TypeDescriptorImpl

use of org.apache.derby.catalog.types.TypeDescriptorImpl in project derby by apache.

the class MethodCallNode method resolveMethodCall.

protected void resolveMethodCall(String javaClassName, boolean staticMethod) throws StandardException {
    // only allow direct method calls through routines and internal SQL.
    if (routineInfo == null && !internalCall) {
        // See if we are being executed in an internal context
        if ((getCompilerContext().getReliability() & CompilerContext.INTERNAL_SQL_ILLEGAL) != 0) {
            throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, javaClassName + (staticMethod ? "::" : ".") + methodName);
        }
    }
    int count = signature.length;
    ClassInspector classInspector = getClassFactory().getClassInspector();
    String[] parmTypeNames;
    String[] primParmTypeNames = null;
    boolean[] isParam = getIsParam();
    boolean hasDynamicResultSets = hasVarargs() ? false : (routineInfo != null) && (count != 0) && (count != methodParms.length);
    /*
        ** Find the matching method that is public.
        */
    int signatureOffset = methodName.indexOf('(');
    // support Java signatures by checking if the method name contains a '('
    if (signatureOffset != -1) {
        parmTypeNames = parseValidateSignature(methodName, signatureOffset, hasDynamicResultSets);
        methodName = methodName.substring(0, signatureOffset);
        // If the signature is specified then Derby resolves to exactly
        // that method. Setting this flag to false disables the method
        // resolution from automatically optionally repeating the last
        // parameter as needed.
        hasDynamicResultSets = false;
    } else {
        parmTypeNames = getObjectSignature();
    }
    // the actual type of the trailing Java varargs arg is an array
    if (hasVarargs()) {
        parmTypeNames[count - 1] = parmTypeNames[count - 1] + "[]";
    }
    try {
        method = classInspector.findPublicMethod(javaClassName, methodName, parmTypeNames, null, isParam, staticMethod, hasDynamicResultSets, hasVarargs());
        // Also if the DDL specified a signature, then no alternate resolution
        if (signatureOffset == -1 && routineInfo == null) {
            /* If no match, then retry with combinations of object and
                 * primitive types.
                 */
            if (method == null) {
                primParmTypeNames = getPrimitiveSignature(false);
                method = classInspector.findPublicMethod(javaClassName, methodName, parmTypeNames, primParmTypeNames, isParam, staticMethod, hasDynamicResultSets, hasVarargs());
            }
        }
    } catch (ClassNotFoundException e) {
        /*
            ** If one of the classes couldn't be found, just act like the
            ** method couldn't be found.  The error lists all the class names,
            ** which should give the user enough info to diagnose the problem.
            */
        method = null;
    }
    /* Throw exception if no matching signature found */
    if (method == null) {
        throwNoMethodFound(javaClassName, parmTypeNames, primParmTypeNames);
    }
    String typeName = classInspector.getType(method);
    actualMethodReturnType = typeName;
    if (routineInfo == null) {
        /* void methods are only okay for CALL Statements */
        if (typeName.equals("void")) {
            if (!forCallStatement)
                throw StandardException.newException(SQLState.LANG_VOID_METHOD_CALL);
        }
    } else {
        String promoteName = null;
        TypeDescriptorImpl returnType = (TypeDescriptorImpl) routineInfo.getReturnType();
        String requiredType;
        if (returnType == null) {
            // must have a void method for a procedure call.
            requiredType = "void";
        } else {
            TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
            if (returnType.isRowMultiSet() && (routineInfo.getParameterStyle() == RoutineAliasInfo.PS_DERBY_JDBC_RESULT_SET)) {
                requiredType = ResultSet.class.getName();
            } else if (returnType.getTypeId().userType()) {
                requiredType = ((UserDefinedTypeIdImpl) returnType.getTypeId()).getClassName();
            } else {
                requiredType = returnTypeId.getCorrespondingJavaTypeName();
                if (!requiredType.equals(typeName)) {
                    switch(returnType.getJDBCTypeId()) {
                        case java.sql.Types.BOOLEAN:
                        case java.sql.Types.SMALLINT:
                        case java.sql.Types.INTEGER:
                        case java.sql.Types.BIGINT:
                        case java.sql.Types.REAL:
                        case java.sql.Types.DOUBLE:
                            TypeCompiler tc = getTypeCompiler(returnTypeId);
                            requiredType = tc.getCorrespondingPrimitiveTypeName();
                            if (!routineInfo.calledOnNullInput() && routineInfo.getParameterCount() != 0) {
                                promoteName = returnTypeId.getCorrespondingJavaTypeName();
                            }
                            break;
                    }
                }
            }
        }
        boolean foundCorrectType;
        if (ResultSet.class.getName().equals(requiredType)) {
            // allow subtypes of ResultSet too
            try {
                Class<?> actualType = classInspector.getClass(typeName);
                foundCorrectType = ResultSet.class.isAssignableFrom(actualType);
            } catch (ClassNotFoundException cnfe) {
                foundCorrectType = false;
            }
        } else {
            foundCorrectType = requiredType.equals(typeName);
        }
        if (!foundCorrectType) {
            throwNoMethodFound(requiredType + " " + javaClassName, parmTypeNames, primParmTypeNames);
        }
        // type we need to promote to an object so we can return null.
        if (promoteName != null)
            typeName = promoteName;
        // MethodCallNode DERBY-2972
        if (routineInfo.getReturnType() != null)
            setCollationType(routineInfo.getReturnType().getCollationType());
    }
    setJavaTypeName(typeName);
    methodParameterTypes = classInspector.getParameterTypes(method);
    String methodParameter = null;
    for (int i = 0; i < methodParameterTypes.length; i++) {
        methodParameter = methodParameterTypes[i];
        if (routineInfo != null) {
            if (i < routineInfo.getParameterCount()) {
                int parameterMode = routineInfo.getParameterModes()[getRoutineArgIdx(i)];
                switch(parameterMode) {
                    case (ParameterMetaData.parameterModeIn):
                        break;
                    case (ParameterMetaData.parameterModeInOut):
                        // we need to see if the type of the array is
                        // primitive, not the array itself.
                        methodParameter = stripOneArrayLevel(methodParameter);
                        break;
                    case (ParameterMetaData.parameterModeOut):
                        // value is not obtained *from* parameter.
                        continue;
                }
            }
        }
        // 
        if (hasVarargs() && (i >= getFirstVarargIdx())) {
            methodParameter = stripOneArrayLevel(methodParameter);
        }
        if (ClassInspector.primitiveType(methodParameter)) {
            // corresponding to the vararg
            if (i < methodParms.length) {
                methodParms[i].castToPrimitive(true);
            }
        }
    }
    // casting may be needed on the trailing varargs
    if (hasVarargs()) {
        int firstVarargIdx = getFirstVarargIdx();
        int trailingVarargCount = methodParms.length - firstVarargIdx;
        // the first vararg was handled in the preceding loop
        for (int i = 1; i < trailingVarargCount; i++) {
            if (ClassInspector.primitiveType(methodParameter)) {
                methodParms[i + firstVarargIdx].castToPrimitive(true);
            }
        }
    }
    /* Set type info for any null parameters */
    if (someParametersAreNull()) {
        setNullParameterInfo(methodParameterTypes);
    }
    /* bug 4450 - if the callable statement is ? = call form, generate the metadata
		infor for the return parameter. We don't really need that info in order to
		execute the callable statement. But with jdbc3.0, this information should be
		made available for return parameter through ParameterMetaData class.
		Parser sets a flag in compilercontext if ? = call. If the flag is set,
		we generate the metadata info for the return parameter and reset the flag
		in the compilercontext for future call statements*/
    DataTypeDescriptor dts = DataTypeDescriptor.getSQLDataTypeDescriptor(typeName);
    if (getCompilerContext().getReturnParameterFlag()) {
        getParameterTypes()[0] = dts;
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) UserDefinedTypeIdImpl(org.apache.derby.catalog.types.UserDefinedTypeIdImpl) ClassInspector(org.apache.derby.iapi.services.loader.ClassInspector) ResultSet(java.sql.ResultSet) TypeDescriptorImpl(org.apache.derby.catalog.types.TypeDescriptorImpl) TypeCompiler(org.apache.derby.iapi.sql.compile.TypeCompiler)

Aggregations

TypeDescriptorImpl (org.apache.derby.catalog.types.TypeDescriptorImpl)3 ResultSet (java.sql.ResultSet)1 UserDefinedTypeIdImpl (org.apache.derby.catalog.types.UserDefinedTypeIdImpl)1 ClassInspector (org.apache.derby.iapi.services.loader.ClassInspector)1 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)1 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)1 TypeId (org.apache.derby.iapi.types.TypeId)1