Search in sources :

Example 56 with DataTypeDescriptor

use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.

the class StaticMethodCallNode method resolveRoutine.

/**
 * Resolve a routine. Obtain a list of routines from the data dictionary
 * of the correct type (functions or procedures) and name.
 * Pick the best routine from the list. Currently only a single routine
 * with a given type and name is allowed, thus if changes are made to
 * support overloaded routines, careful code inspection and testing will
 * be required.
 */
private void resolveRoutine(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates, SchemaDescriptor sd, boolean noSchema) throws StandardException {
    if (sd.getUUID() != null) {
        List<AliasDescriptor> list = getDataDictionary().getRoutineList(sd.getUUID().toString(), methodName, forCallStatement ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR);
        for (int i = list.size() - 1; i >= 0; i--) {
            AliasDescriptor proc = list.get(i);
            RoutineAliasInfo rai = (RoutineAliasInfo) proc.getAliasInfo();
            int parameterCount = rai.getParameterCount();
            boolean hasVarargs = rai.hasVarargs();
            if (hasVarargs) {
                // for the trailing varargs argument
                if (methodParms.length < (parameterCount - 1)) {
                    continue;
                }
            } else if (parameterCount != methodParms.length) {
                continue;
            }
            // pre-form the method signature. If it is a dynamic result set procedure
            // then we need to add in the ResultSet array
            TypeDescriptor[] parameterTypes = rai.getParameterTypes();
            int sigParameterCount = parameterCount;
            if (rai.getMaxDynamicResultSets() > 0) {
                sigParameterCount++;
            }
            signature = new JSQLType[sigParameterCount];
            for (int p = 0; p < parameterCount; p++) {
                // find the declared type.
                TypeDescriptor td = parameterTypes[p];
                TypeId typeId = TypeId.getTypeId(td);
                TypeId parameterTypeId = typeId;
                // if it's an OUT or INOUT parameter we need an array.
                int parameterMode = rai.getParameterModes()[getRoutineArgIdx(rai, p)];
                if (parameterMode != (ParameterMetaData.parameterModeIn)) {
                    String arrayType;
                    switch(typeId.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:
                            arrayType = getTypeCompiler(typeId).getCorrespondingPrimitiveTypeName().concat("[]");
                            break;
                        default:
                            arrayType = typeId.getCorrespondingJavaTypeName().concat("[]");
                            break;
                    }
                    typeId = TypeId.getUserDefinedTypeId(arrayType);
                }
                // this is the type descriptor of the require method parameter
                DataTypeDescriptor methoddtd = new DataTypeDescriptor(typeId, td.getPrecision(), td.getScale(), td.isNullable(), td.getMaximumWidth());
                signature[p] = new JSQLType(methoddtd);
                // this is the SQL type of the procedure parameter.
                DataTypeDescriptor paramdtd = new DataTypeDescriptor(parameterTypeId, td.getPrecision(), td.getScale(), td.isNullable(), td.getMaximumWidth());
                // if this is the last argument of a varargs routine...
                if (hasVarargs && (p == parameterCount - 1)) {
                    // 
                    for (int idx = p; idx < methodParms.length; idx++) {
                        coerceMethodParameter(fromList, subqueryList, aggregates, rai, methodParms.length, paramdtd, parameterTypeId, parameterMode, idx);
                    }
                } else // NOT the last argument of a varargs routine
                {
                    coerceMethodParameter(fromList, subqueryList, aggregates, rai, methodParms.length, paramdtd, parameterTypeId, parameterMode, p);
                }
            }
            if (sigParameterCount != parameterCount) {
                DataTypeDescriptor dtd = new DataTypeDescriptor(TypeId.getUserDefinedTypeId("java.sql.ResultSet[]"), 0, 0, false, -1);
                signature[parameterCount] = new JSQLType(dtd);
            }
            this.routineInfo = rai;
            ad = proc;
            // SQL, note that we are in system code.
            if (sd.isSystemSchema() && (routineInfo.getReturnType() == null) && routineInfo.getSQLAllowed() != RoutineAliasInfo.NO_SQL) {
                isSystemCode = true;
            }
            routineDefiner = sd.getAuthorizationId();
            break;
        }
    }
    if ((ad == null) && (methodParms.length == 1)) {
        ad = AggregateNode.resolveAggregate(getDataDictionary(), sd, methodName, noSchema);
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) JSQLType(org.apache.derby.iapi.types.JSQLType) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor)

Example 57 with DataTypeDescriptor

use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.

the class StaticMethodCallNode method coerceMethodParameter.

/**
 * <p>
 * Coerce an actual method parameter to the declared type of the corresponding
 * routine argument.
 * </p>
 */
private void coerceMethodParameter(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates, RoutineAliasInfo rai, // number of declared routine args
int parameterCount, // declared type of routine arg
DataTypeDescriptor paramdtd, // declared type id of routine arg
TypeId parameterTypeId, int parameterMode, // index of actual method parameter in array of parameters
int p) throws StandardException {
    // check parameter is a ? node for INOUT and OUT parameters.
    ValueNode sqlParamNode = null;
    if (methodParms[p] instanceof SQLToJavaValueNode) {
        SQLToJavaValueNode sql2j = (SQLToJavaValueNode) methodParms[p];
        sqlParamNode = sql2j.getSQLValueNode();
    }
    boolean isParameterMarker = true;
    if ((sqlParamNode == null) || !sqlParamNode.requiresTypeFromContext()) {
        if (parameterMode != (ParameterMetaData.parameterModeIn)) {
            throw StandardException.newException(SQLState.LANG_DB2_PARAMETER_NEEDS_MARKER, RoutineAliasInfo.parameterMode(parameterMode), rai.getParameterNames()[p]);
        }
        isParameterMarker = false;
    } else {
        if (applicationParameterNumbers == null) {
            applicationParameterNumbers = new int[parameterCount];
        }
        if (sqlParamNode instanceof UnaryOperatorNode) {
            ParameterNode pn = ((UnaryOperatorNode) sqlParamNode).getParameterOperand();
            applicationParameterNumbers[p] = pn.getParameterNumber();
        } else {
            applicationParameterNumbers[p] = ((ParameterNode) sqlParamNode).getParameterNumber();
        }
    }
    boolean needCast = false;
    if (!isParameterMarker) {
        // type of the procedure parameter.
        if (sqlParamNode instanceof UntypedNullConstantNode) {
            sqlParamNode.setType(paramdtd);
        } else {
            DataTypeDescriptor dts;
            TypeId argumentTypeId;
            if (sqlParamNode != null) {
                // a node from the SQL world
                argumentTypeId = sqlParamNode.getTypeId();
                dts = sqlParamNode.getTypeServices();
            } else {
                // a node from the Java world
                dts = DataTypeDescriptor.getSQLDataTypeDescriptor(methodParms[p].getJavaTypeName());
                if (dts == null) {
                    throw StandardException.newException(SQLState.LANG_NO_CORRESPONDING_S_Q_L_TYPE, methodParms[p].getJavaTypeName());
                }
                argumentTypeId = dts.getTypeId();
            }
            if (!getTypeCompiler(parameterTypeId).storable(argumentTypeId, getClassFactory())) {
                throw StandardException.newException(SQLState.LANG_NOT_STORABLE, parameterTypeId.getSQLTypeName(), argumentTypeId.getSQLTypeName());
            }
            // if it's not an exact length match then some cast will be needed.
            if (!paramdtd.isExactTypeAndLengthMatch(dts)) {
                needCast = true;
            }
        }
    } else {
        // correctly as 10 characters long.
        if (parameterTypeId.variableLength()) {
            if (parameterMode != (ParameterMetaData.parameterModeOut)) {
                needCast = true;
            }
        }
    }
    if (needCast) {
        if (sqlParamNode == null) {
            sqlParamNode = new JavaToSQLValueNode(methodParms[p], getContextManager());
        }
        ValueNode castNode = makeCast(sqlParamNode, paramdtd, getContextManager());
        methodParms[p] = new SQLToJavaValueNode(castNode, getContextManager());
        methodParms[p] = methodParms[p].bindExpression(fromList, subqueryList, aggregates);
    }
    // in parameter meta data
    if (isParameterMarker) {
        sqlParamNode.setType(paramdtd);
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 58 with DataTypeDescriptor

use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.

the class SubqueryNode method setDataTypeServices.

private void setDataTypeServices(ResultColumnList resultColumns) throws StandardException {
    DataTypeDescriptor dts;
    /* Set the result type for this subquery (must be nullable).
		 * Quantified predicates will return boolean.
		 * However, the return type of the subquery's result list will 
		 * probably not be boolean at this point, because we do not
		 * transform the subquery (other than EXISTS) into 
		 * (select true/false ...) until preprocess().  So, we force 
		 * the return type to boolean.
		 */
    if (subqueryType == EXPRESSION_SUBQUERY) {
        dts = resultColumns.elementAt(0).getTypeServices();
    } else {
        dts = getTrueNode().getTypeServices();
    }
    setType(dts.getNullabilityType(true));
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 59 with DataTypeDescriptor

use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.

the class SumAvgAggregateDefinition method getAggregator.

/**
 * Determines the result datatype.  Accept NumberDataValues
 * only.
 * <P>
 * <I>Note</I>: In the future you should be able to do
 * a sum user data types.  One option would be to run
 * sum on anything that implements plus().  In which
 * case avg() would need divide().
 *
 * @param inputType	the input type, either a user type or a java.lang object
 *
 * @return the output Class (null if cannot operate on
 *	value expression of this type.
 */
public final DataTypeDescriptor getAggregator(DataTypeDescriptor inputType, StringBuffer aggregatorClass) {
    try {
        TypeId compType = inputType.getTypeId();
        CompilerContext cc = (CompilerContext) QueryTreeNode.getContext(CompilerContext.CONTEXT_ID);
        TypeCompilerFactory tcf = cc.getTypeCompilerFactory();
        TypeCompiler tc = tcf.getTypeCompiler(compType);
        /*
			** If the class implements NumberDataValue, then we
			** are in business.  Return type is same as input
			** type.
			*/
        if (compType.isNumericTypeId()) {
            aggregatorClass.append(getAggregatorClassName());
            DataTypeDescriptor outDts = tc.resolveArithmeticOperation(inputType, inputType, getOperator());
            /*
				** SUM and AVG may return null
				*/
            return outDts.getNullabilityType(true);
        }
    } catch (StandardException e) {
        if (SanityManager.DEBUG) {
            SanityManager.THROWASSERT("Unexpected exception", e);
        }
    }
    return null;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) StandardException(org.apache.derby.shared.common.error.StandardException) TypeCompilerFactory(org.apache.derby.iapi.sql.compile.TypeCompilerFactory) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) TypeCompiler(org.apache.derby.iapi.sql.compile.TypeCompiler)

Example 60 with DataTypeDescriptor

use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.

the class TableElementList method checkIndexPageSizeProperty.

/**
 * Checks if the index should use a larger page size.
 *
 * If the columns in the index are large, and if the user hasn't already
 * specified a page size to use, then we may need to default to the
 * large page size in order to get an index with sufficiently large pages.
 * For example, this DDL should use a larger page size for the index
 * that backs the PRIMARY KEY constraint:
 *
 * create table t (x varchar(1000) primary key)
 *
 * @param cdn Constraint node
 *
 * @return properties to use for creating the index
 */
private Properties checkIndexPageSizeProperty(ConstraintDefinitionNode cdn) throws StandardException {
    Properties result = cdn.getProperties();
    if (result == null)
        result = new Properties();
    if (result.get(Property.PAGE_SIZE_PARAMETER) != null || PropertyUtil.getServiceProperty(getLanguageConnectionContext().getTransactionCompile(), Property.PAGE_SIZE_PARAMETER) != null) {
        // is set for the whole database or just set on this statement.
        return result;
    }
    int approxLength = 0;
    for (ResultColumn rc : cdn.getColumnList()) {
        String colName = rc.getName();
        DataTypeDescriptor dtd;
        if (td == null)
            dtd = getColumnDataTypeDescriptor(colName);
        else
            dtd = getColumnDataTypeDescriptor(colName, td);
        // skip the length checking if the column doesn't exist.
        if (dtd != null)
            approxLength += dtd.getTypeId().getApproximateLengthInBytes(dtd);
    }
    if (approxLength > Property.IDX_PAGE_SIZE_BUMP_THRESHOLD) {
        result.put(Property.PAGE_SIZE_PARAMETER, Property.PAGE_SIZE_DEFAULT_LONG);
    }
    return result;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) Properties(java.util.Properties)

Aggregations

DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)99 TypeId (org.apache.derby.iapi.types.TypeId)32 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)14 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)14 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)9 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)8 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)8 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)7 UUID (org.apache.derby.catalog.UUID)5 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)5 ResultColumnDescriptor (org.apache.derby.iapi.sql.ResultColumnDescriptor)5 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)5 StandardException (org.apache.derby.shared.common.error.StandardException)5 Properties (java.util.Properties)4 UserDefinedTypeIdImpl (org.apache.derby.catalog.types.UserDefinedTypeIdImpl)4 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)4 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)3 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)3 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)3 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)3