Search in sources :

Example 91 with DataTypeDescriptor

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

the class LikeEscapeOperatorNode method finishBindExpr.

private void finishBindExpr() throws StandardException {
    // deal with compatability of operands and result type
    bindComparisonOperator();
    /*
        ** The result type of LIKE is Boolean
        */
    boolean nullableResult = receiver.getTypeServices().isNullable() || leftOperand.getTypeServices().isNullable();
    if (rightOperand != null) {
        nullableResult |= rightOperand.getTypeServices().isNullable();
    }
    setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID, nullableResult));
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 92 with DataTypeDescriptor

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

the class LikeEscapeOperatorNode method bindExpression.

/**
 * implement binding for like expressions.
 * <p>
 * overrides BindOperatorNode.bindExpression because like has special
 * requirements for parameter binding.
 *
 * @return  The new top of the expression tree.
 *
 * @exception StandardException thrown on failure
 */
@Override
ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
    super.bindExpression(fromList, subqueryList, aggregates);
    String pattern = null;
    if (!(leftOperand.requiresTypeFromContext()) && !(leftOperand.getTypeId().isStringTypeId())) {
        throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "LIKE", "FUNCTION");
    }
    // escape must be a string or a parameter
    if ((rightOperand != null) && !(rightOperand.requiresTypeFromContext()) && !(rightOperand.getTypeId().isStringTypeId())) {
        throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "LIKE", "FUNCTION");
    }
    /* 
        *  Is there a ? parameter on the left? ie. "? like 'Derby'"
        *
        *  Do left first because its length is always maximum;
        *  a parameter on the right copies its length from
        *  the left, since it won't match if it is any longer than it.
        */
    if (receiver.requiresTypeFromContext()) {
        receiver.setType(new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), true));
        // collation from the compilation schema.
        if (!leftOperand.requiresTypeFromContext()) {
            receiver.setCollationInfo(leftOperand.getTypeServices());
        } else if (rightOperand != null && !rightOperand.requiresTypeFromContext()) {
            receiver.setCollationInfo(rightOperand.getTypeServices());
        } else {
            receiver.setCollationUsingCompilationSchema();
        }
    }
    /* 
         *  Is there a ? parameter for the PATTERN of LIKE? ie. "column like ?"
         *  
         *  Copy from the receiver -- legal if both are parameters,
         *  both will be max length.
         *  REMIND: should nullability be copied, or set to true?
         */
    if (leftOperand.requiresTypeFromContext()) {
        /*
            * Set the pattern to the type of the left parameter, if
            * the left is a string, otherwise set it to be VARCHAR. 
            */
        if (receiver.getTypeId().isStringTypeId()) {
            leftOperand.setType(receiver.getTypeServices());
        } else {
            leftOperand.setType(new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), true));
        }
        // collation of ? operand should be picked up from the context.
        // By the time we come here, receiver will have correct collation
        // set on it and hence we can rely on it to get correct collation
        // for the other ? in LIKE clause
        leftOperand.setCollationInfo(receiver.getTypeServices());
    }
    if (rightOperand != null && rightOperand.requiresTypeFromContext()) {
        /*
             * Set the pattern to the type of the left parameter, if
             * the left is a string, otherwise set it to be VARCHAR. 
             */
        if (receiver.getTypeId().isStringTypeId()) {
            rightOperand.setType(receiver.getTypeServices());
        } else {
            rightOperand.setType(new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), true));
        }
        // collation of ? operand should be picked up from the context.
        // By the time we come here, receiver will have correct collation
        // set on it and hence we can rely on it to get correct collation
        // for the other ? in LIKE clause
        rightOperand.setCollationInfo(receiver.getTypeServices());
    }
    bindToBuiltIn();
    /* The receiver must be a string type
        */
    if (!receiver.getTypeId().isStringTypeId()) {
        throw StandardException.newException(SQLState.LANG_DB2_FUNCTION_INCOMPATIBLE, "LIKE", "FUNCTION");
    }
    /* If either the left or right operands are non-string types,
         * then we generate an implicit cast to VARCHAR.
         */
    if (!leftOperand.getTypeId().isStringTypeId()) {
        leftOperand = castArgToString(leftOperand);
    }
    if (rightOperand != null) {
        rightOperand = castArgToString(rightOperand);
    }
    /* 
         * Remember whether or not the right side (the like pattern) is a string 
         * constant.  We need to remember here so that we can transform LIKE 
         * 'constant' into = 'constant' for non unicode based collation columns.
         */
    boolean leftConstant = (leftOperand instanceof CharConstantNode);
    if (leftConstant) {
        pattern = ((CharConstantNode) leftOperand).getString();
    }
    boolean rightConstant = (rightOperand instanceof CharConstantNode);
    if (rightConstant) {
        escape = ((CharConstantNode) rightOperand).getString();
        if (escape.length() != 1) {
            throw StandardException.newException(SQLState.LANG_INVALID_ESCAPE_CHARACTER, escape);
        }
    } else if (rightOperand == null) {
        // No Escape clause: Let optimization continue for the = case below
        rightConstant = true;
    }
    // and derivation.
    if (!receiver.getTypeServices().compareCollationInfo(leftOperand.getTypeServices())) {
        // throw error.
        throw StandardException.newException(SQLState.LANG_LIKE_COLLATION_MISMATCH, receiver.getTypeServices().getSQLstring(), receiver.getTypeServices().getCollationName(), leftOperand.getTypeServices().getSQLstring(), leftOperand.getTypeServices().getCollationName());
    }
    if ((receiver instanceof ColumnReference) && leftConstant && rightConstant) {
        if (Like.isOptimizable(pattern)) {
            String newPattern = null;
            if (escape != null) {
                /* we return a new pattern stripped of ESCAPE chars */
                newPattern = Like.stripEscapesNoPatternChars(pattern, escape.charAt(0));
            } else if (pattern.indexOf('_') == -1 && pattern.indexOf('%') == -1) {
                // no pattern characters.
                newPattern = pattern;
            }
            if (newPattern != null) {
                // met all conditions, transform LIKE into a "LIKE and ="
                ValueNode leftClone = receiver.getClone();
                // Remember that we did xform, see preprocess()
                addedEquals = true;
                // create equals node of the form (eg. column like 'Derby' :
                // =
                // /   \
                // column  'Derby'
                BinaryComparisonOperatorNode equals = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_EQUALS, leftClone, new CharConstantNode(newPattern, getContextManager()), false, getContextManager());
                // Set forQueryRewrite to bypass comparability checks
                equals.setForQueryRewrite(true);
                equals = (BinaryComparisonOperatorNode) equals.bindExpression(fromList, subqueryList, aggregates);
                // create new and node and hook in "equals" the new "=' node
                // 
                // AND
                // /   \
                // LIKE   =
                // / \
                // column 'Derby'
                AndNode newAnd = new AndNode(this, equals, getContextManager());
                finishBindExpr();
                newAnd.postBindFixup();
                return newAnd;
            }
        }
    }
    finishBindExpr();
    return this;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 93 with DataTypeDescriptor

use of org.apache.derby.iapi.types.DataTypeDescriptor 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)

Example 94 with DataTypeDescriptor

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

the class ModifyColumnNode method checkUserType.

/**
 * Check the validity of a user type.  Checks that
 * 1. the column type is either varchar, ....
 * 2. is the same type after the alter.
 * 3. length is greater than the old length.
 *
 * @exception StandardException		Thrown on error
 */
@Override
void checkUserType(TableDescriptor td) throws StandardException {
    if (kind != K_MODIFY_COLUMN_TYPE) {
        // nothing to do if user not changing length
        return;
    }
    ColumnDescriptor cd = td.getColumnDescriptor(name);
    if (cd == null) {
        throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, name, td.getName());
    }
    DataTypeDescriptor oldType = cd.getType();
    setNullability(oldType.isNullable());
    // can't change types yet.
    if (!(oldType.getTypeId().equals(getType().getTypeId()))) {
        throw StandardException.newException(SQLState.LANG_MODIFY_COLUMN_CHANGE_TYPE, name);
    }
    // can only alter the length of varchar, bitvarying columns
    String typeName = getType().getTypeName();
    if (!(typeName.equals(TypeId.VARCHAR_NAME)) && !(typeName.equals(TypeId.VARBIT_NAME)) && !(typeName.equals(TypeId.BLOB_NAME)) && !(typeName.equals(TypeId.CLOB_NAME))) {
        throw StandardException.newException(SQLState.LANG_MODIFY_COLUMN_INVALID_TYPE);
    }
    // cannot decrease the length of a column
    if (getType().getMaximumWidth() < oldType.getMaximumWidth()) {
        throw StandardException.newException(SQLState.LANG_MODIFY_COLUMN_INVALID_LENGTH, name);
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)

Example 95 with DataTypeDescriptor

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

the class DataDictionaryImpl method updateSPS.

/**
 * Updates SYS.SYSSTATEMENTS with the info from the
 * SPSD.
 *
 * @param spsd	The descriptor to add
 * @param tc			The transaction controller
 * @param recompile Whether to recompile or invalidate
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void updateSPS(SPSDescriptor spsd, TransactionController tc, boolean recompile) throws StandardException {
    ExecIndexRow keyRow1 = null;
    ExecRow row;
    DataValueDescriptor idOrderable;
    TabInfoImpl ti = getNonCoreTI(SYSSTATEMENTS_CATALOG_NUM);
    SYSSTATEMENTSRowFactory rf = (SYSSTATEMENTSRowFactory) ti.getCatalogRowFactory();
    int[] updCols;
    if (recompile) {
        updCols = new int[] { SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_TEXT, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_LASTCOMPILED, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_USINGTEXT, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE };
    } else {
        // This is an invalidation request. Update the VALID column (to
        // false) and clear the plan stored in the CONSTANTSTATE column.
        updCols = new int[] { SYSSTATEMENTSRowFactory.SYSSTATEMENTS_VALID, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_CONSTANTSTATE };
    }
    idOrderable = getIDValueAsCHAR(spsd.getUUID());
    /* Set up the start/stop position for the scan */
    keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
    keyRow1.setColumn(1, idOrderable);
    row = // don't compile
    rf.makeSYSSTATEMENTSrow(// don't compile
    false, spsd);
    /*
		** Not updating any indexes
		*/
    boolean[] bArray = new boolean[2];
    /*
		** Partial update
		*/
    ti.updateRow(keyRow1, row, SYSSTATEMENTSRowFactory.SYSSTATEMENTS_INDEX1_ID, bArray, updCols, tc);
    // parameter descriptors, so we are done.
    if (!recompile) {
        return;
    }
    /*
		** Set the defaults and datatypes for the parameters, if
		** there are parameters.
		*/
    DataTypeDescriptor[] params = spsd.getParams();
    if (params == null) {
        return;
    }
    // Update the parameter descriptors by dropping the existing ones
    // and recreating them. If this is the first time the SPS is being
    // compiled, the drop operation will be a no-op.
    dropAllColumnDescriptors(spsd.getUUID(), tc);
    addSPSParams(spsd, tc);
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow)

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