Search in sources :

Example 6 with TypeId

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

the class MethodCallNode method parseValidateSignature.

/**
 * Parse the user supplied signature for a method and validate
 * it, need to match the number of parameters passed in and match
 * the valid types for the parameter.
 * @param offset Character offset of first paren
 * @param hasDynamicResultSets Can ResultSet[] parameters be specified.
 * @return The valid array of types for resolution.
 * @throws StandardException
 */
private String[] parseValidateSignature(String externalName, int offset, boolean hasDynamicResultSets) throws StandardException {
    int siglen = externalName.length();
    // character and that the last character is a close paren
    if (((offset + 1) == siglen) || (externalName.charAt(siglen - 1) != ')'))
        // invalid
        throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
    StringTokenizer st = new StringTokenizer(externalName.substring(offset + 1, siglen - 1), ",", true);
    String[] signatureTypes = new String[signature.length];
    int count;
    boolean seenClass = false;
    for (count = 0; st.hasMoreTokens(); ) {
        String type = st.nextToken().trim();
        // check sequence is <class><comma>class> etc.
        if (",".equals(type)) {
            if (!seenClass)
                // invalid
                throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
            seenClass = false;
            continue;
        } else {
            if (type.length() == 0)
                // invalid
                throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
            seenClass = true;
            count++;
        }
        if (count > signature.length) {
            if (hasDynamicResultSets) {
                // Allow any number of dynamic result set holders
                // but they must match the exact type.
                String rsType = signature[signature.length - 1].getSQLType().getTypeId().getCorrespondingJavaTypeName();
                if (!type.equals(rsType))
                    throw StandardException.newException(SQLState.LANG_DATA_TYPE_GET_MISMATCH, type, rsType);
                if (signatureTypes.length == signature.length) {
                    // expand once
                    String[] sigs = new String[st.countTokens()];
                    System.arraycopy(signatureTypes, 0, sigs, 0, signatureTypes.length);
                    signatureTypes = sigs;
                }
                signatureTypes[count - 1] = type;
                continue;
            }
            throw StandardException.newException(SQLState.SQLJ_SIGNATURE_PARAMETER_COUNT, Integer.toString(count), // too many types
            Integer.toString(signature.length));
        }
        TypeId paramTypeId = signature[count - 1].getSQLType().getTypeId();
        // Does it match the object name
        if (type.equals(paramTypeId.getCorrespondingJavaTypeName())) {
            signatureTypes[count - 1] = type;
            continue;
        }
        // how about the primitive name
        if ((paramTypeId.isNumericTypeId() && !paramTypeId.isDecimalTypeId()) || paramTypeId.isBooleanTypeId()) {
            TypeCompiler tc = getTypeCompiler(paramTypeId);
            if (type.equals(tc.getCorrespondingPrimitiveTypeName())) {
                signatureTypes[count - 1] = type;
                continue;
            }
        }
        throw StandardException.newException(SQLState.LANG_DATA_TYPE_GET_MISMATCH, type, // type conversion error
        paramTypeId.getSQLTypeName());
    }
    // Did signature end with trailing comma?
    if (count != 0 && !seenClass)
        // invalid
        throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
    if (count < signatureTypes.length) {
        if (hasDynamicResultSets) {
            // dynamic results at runtime
            if (count == (signature.length - 1)) {
                String[] sigs = new String[count];
                System.arraycopy(signatureTypes, 0, sigs, 0, count);
                return sigs;
            }
        }
        throw StandardException.newException(SQLState.SQLJ_SIGNATURE_PARAMETER_COUNT, Integer.toString(count), // too few types
        Integer.toString(signature.length));
    }
    return signatureTypes;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) StringTokenizer(java.util.StringTokenizer) TypeCompiler(org.apache.derby.iapi.sql.compile.TypeCompiler)

Example 7 with TypeId

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

the class JoinNode method deferredBindExpressions.

private void deferredBindExpressions(FromList fromListParam) throws StandardException {
    ContextManager cm = getContextManager();
    CompilerContext cc = getCompilerContext();
    /* Bind the expressions in the join clause */
    subqueryList = new SubqueryList(cm);
    aggregates = new ArrayList<AggregateNode>();
    /* ON clause */
    if (joinClause != null) {
        joinClause = bindExpression(joinClause, true, true, "ON");
    } else /* USING clause */
    if (usingClause != null) {
        /* Build a join clause from the usingClause, using the
			 * exposed names in the left and right RSNs.
			 * For each column in the list, we generate 2 ColumnReferences,
			 * 1 for the left and 1 for the right.  We bind each of these
			 * to the appropriate side and build an equality predicate
			 * between the 2.  We bind the = and AND nodes by hand because
			 * we have to bind the ColumnReferences a side at a time.
			 * We need to bind the CRs a side at a time to ensure that
			 * we don't find an bogus ambiguous column reference. (Bug 377)
			 */
        joinClause = new BooleanConstantNode(true, cm);
        for (ResultColumn rc : usingClause) {
            BinaryComparisonOperatorNode equalsNode;
            ColumnReference leftCR;
            ColumnReference rightCR;
            /* Create and bind the left CR */
            fromListParam.insertElementAt(leftResultSet, 0);
            leftCR = new ColumnReference(rc.getName(), ((FromTable) leftResultSet).getTableName(), cm);
            leftCR = (ColumnReference) leftCR.bindExpression(fromListParam, subqueryList, aggregates);
            fromListParam.removeElementAt(0);
            /* Create and bind the right CR */
            fromListParam.insertElementAt(rightResultSet, 0);
            rightCR = new ColumnReference(rc.getName(), ((FromTable) rightResultSet).getTableName(), cm);
            rightCR = (ColumnReference) rightCR.bindExpression(fromListParam, subqueryList, aggregates);
            fromListParam.removeElementAt(0);
            /* Create and insert the new = condition */
            equalsNode = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_EQUALS, leftCR, rightCR, false, cm);
            equalsNode.bindComparisonOperator();
            // Create a new join clause by ANDing the new = condition and
            // the old join clause.
            AndNode newJoinClause = new AndNode(equalsNode, joinClause, cm);
            newJoinClause.postBindFixup();
            joinClause = newJoinClause;
        }
    }
    if (joinClause != null) {
        /* If joinClause is a parameter, (where ?), then we assume
			 * it will be a nullable boolean.
			 */
        if (joinClause.requiresTypeFromContext()) {
            joinClause.setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID, true));
        }
        /*
			** Is the datatype of the JOIN clause BOOLEAN?
			**
			** NOTE: This test is not necessary in SQL92 entry level, because
			** it is syntactically impossible to have a non-Boolean JOIN clause
			** in that level of the standard.  But we intend to extend the
			** language to allow Boolean user functions in the JOIN clause,
			** so we need to test for the error condition.
			*/
        TypeId joinTypeId = joinClause.getTypeId();
        /* If the where clause is not a built-in type, then generate a bound 
			 * conversion tree to a built-in type.
			 */
        if (joinTypeId.userType()) {
            joinClause = joinClause.genSQLJavaSQLTree();
        }
        if (!joinClause.getTypeServices().getTypeId().equals(TypeId.BOOLEAN_ID)) {
            throw StandardException.newException(SQLState.LANG_NON_BOOLEAN_JOIN_CLAUSE, joinClause.getTypeServices().getTypeId().getSQLTypeName());
        }
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) ContextManager(org.apache.derby.iapi.services.context.ContextManager)

Example 8 with TypeId

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

the class MaxMinAggregateDefinition 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 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) {
    LanguageConnectionContext lcc = (LanguageConnectionContext) QueryTreeNode.getContext(LanguageConnectionContext.CONTEXT_ID);
    /*
			** MIN and MAX may return null
			*/
    DataTypeDescriptor dts = inputType.getNullabilityType(true);
    TypeId compType = dts.getTypeId();
    /*
		** If the class implements NumberDataValue, then we
		** are in business.  Return type is same as input
		** type.
		*/
    if (compType.orderable(lcc.getLanguageConnectionFactory().getClassFactory())) {
        aggregatorClass.append(ClassName.MaxMinAggregator);
        return dts;
    }
    return null;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 9 with TypeId

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

the class ResultColumnList method setUnionResultExpression.

/**
 * Set up the result expressions for a UNION, INTERSECT, or EXCEPT:
 *	o Verify union type compatiblity
 *	o Get dominant type for result (type + max length + nullability)
 *  o Create a new ColumnReference with dominant type and name of from this
 *    RCL and make that the new expression.
 *  o Set the type info for in the ResultColumn to the dominant type
 *
 * NOTE - We are assuming that caller has generated a new RCL for the UNION
 * with the same names as the left side's RCL and copies of the expressions.
 *
 * @param otherRCL	RCL from other side of the UNION.
 * @param tableNumber	The tableNumber for the UNION.
 * @param level		The nesting level for the UNION.
 * @param operatorName "UNION", "INTERSECT", or "EXCEPT"
 *
 * @exception StandardException			Thrown on error
 */
void setUnionResultExpression(ResultColumnList otherRCL, int tableNumber, int level, String operatorName) throws StandardException {
    TableName dummyTN;
    if (SanityManager.DEBUG) {
        if (visibleSize() != otherRCL.visibleSize()) {
            SanityManager.THROWASSERT("visibleSize() = (" + visibleSize() + ") is expected to equal otherRCL.visibleSize (" + otherRCL.visibleSize() + ")");
        }
        // Generated grouping columns and unselected ORDER BY columns
        // should have been removed for the RCL of a SetOperatorNode, so
        // that size and visible size are equal (DERBY-3764).
        SanityManager.ASSERT(size() == visibleSize(), "size() and visibleSize() should be equal");
    }
    /* Make a dummy TableName to be shared by all new CRs */
    dummyTN = new TableName(null, null, getContextManager());
    int size = visibleSize();
    for (int index = 0; index < size; index++) {
        ColumnReference newCR;
        ResultColumn thisRC = elementAt(index);
        ResultColumn otherRC = otherRCL.elementAt(index);
        ValueNode thisExpr = thisRC.getExpression();
        ValueNode otherExpr = otherRC.getExpression();
        // not be 'autoincrement'.
        if (!otherRC.isAutoincrementGenerated() && thisRC.isAutoincrementGenerated()) {
            thisRC.resetAutoincrementGenerated();
        }
        /*
			** If there are ? parameters in the ResultColumnList of a row
			** in a table constructor, their types will not be set.  Just skip
			** these - their types will be set later.  Each ? parameter will
			** get the type of the first non-? in its column, so it can't
			** affect the final dominant type.  It's possible that all the
			** rows for a particular column will have ? parameters - this is
			** an error condition that will be caught later.
			*/
        TypeId thisTypeId = thisExpr.getTypeId();
        if (thisTypeId == null)
            continue;
        TypeId otherTypeId = otherExpr.getTypeId();
        if (otherTypeId == null)
            continue;
        /* 
			** Check type compatability.
			*/
        ClassFactory cf = getClassFactory();
        if (!unionCompatible(thisExpr, otherExpr)) {
            throw StandardException.newException(SQLState.LANG_NOT_UNION_COMPATIBLE, thisTypeId.getSQLTypeName(), otherTypeId.getSQLTypeName(), operatorName);
        }
        DataTypeDescriptor resultType = thisExpr.getTypeServices().getDominantType(otherExpr.getTypeServices(), cf);
        newCR = new ColumnReference(thisRC.getName(), dummyTN, getContextManager());
        newCR.setType(resultType);
        /* Set the tableNumber and nesting levels in newCR.
			 * If thisExpr is not a CR, then newCR cannot be
			 * correlated, hence source and nesting levels are
			 * the same.
			 */
        if (thisExpr instanceof ColumnReference) {
            newCR.copyFields((ColumnReference) thisExpr);
        } else {
            newCR.setNestingLevel(level);
            newCR.setSourceLevel(level);
        }
        newCR.setTableNumber(tableNumber);
        thisRC.setExpression(newCR);
        thisRC.setType(thisRC.getTypeServices().getDominantType(otherRC.getTypeServices(), cf));
        /* DB2 requires both sides of union to have same name for the result to
			 * have that name. Otherwise, leave it or set it to a generated name */
        if (thisRC.getName() != null && !thisRC.isNameGenerated() && otherRC.getName() != null) {
            /* Result name needs to be changed */
            if (otherRC.isNameGenerated()) {
                thisRC.setName(otherRC.getName());
                thisRC.setNameGenerated(true);
            } else if (!thisRC.getName().equals(otherRC.getName())) {
                /* Both sides have user specified names that don't match */
                thisRC.setName(null);
                thisRC.guaranteeColumnName();
                thisRC.setNameGenerated(true);
            }
        }
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) ClassFactory(org.apache.derby.iapi.services.loader.ClassFactory) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 10 with TypeId

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

the class ColumnDefinitionNode method validateDefault.

/**
 * Check the validity of the default for this node.
 *
 * @param td		The TableDescriptor.
 *
 * @exception StandardException		Thrown on error
 */
void validateDefault(DataDictionary dd, TableDescriptor td) throws StandardException {
    if (defaultNode == null)
        return;
    // Examin whether default value is autoincrement.
    if (isAutoincrement) {
        defaultInfo = createDefaultInfoOfAutoInc();
        return;
    }
    // Judged as default value is constant value.
    CompilerContext cc = getCompilerContext();
    ValueNode defaultTree = defaultNode.getDefaultTree();
    /* bind the default.
		 * Verify that it does not contain any ColumnReferences or subqueries
		 * and that it is type compatable with the column.
		 */
    final int previousReliability = cc.getReliability();
    try {
        /*
				Defaults cannot have dependencies as they
				should just be constants. Code used to exist
				to handle dependencies in defaults, now this
				is under sanity to ensure no dependencies exist.
			 */
        ProviderList apl = null;
        ProviderList prevAPL = null;
        if (SanityManager.DEBUG) {
            apl = new ProviderList();
            prevAPL = cc.getCurrentAuxiliaryProviderList();
            cc.setCurrentAuxiliaryProviderList(apl);
        }
        // Tell the compiler context to only allow deterministic nodes
        cc.setReliability(CompilerContext.DEFAULT_RESTRICTION);
        defaultTree = defaultTree.bindExpression(new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()), (SubqueryList) null, (List<AggregateNode>) null);
        TypeId columnTypeId = getType().getTypeId();
        TypeId defaultTypeId = defaultTree.getTypeId();
        // before checking for 'not storable' errors (42821).
        if (!defaultTypeIsValid(columnTypeId, getType(), defaultTypeId, defaultTree, defaultNode.getDefaultText())) {
            throw StandardException.newException(SQLState.LANG_DB2_INVALID_DEFAULT_VALUE, this.name);
        }
        // Now check 'not storable' errors.
        if (!getTypeCompiler(columnTypeId).storable(defaultTypeId, getClassFactory())) {
            throw StandardException.newException(SQLState.LANG_NOT_STORABLE, columnTypeId.getSQLTypeName(), defaultTypeId.getSQLTypeName());
        }
        // Save off the default text
        // RESOLVEDEFAULT - Convert to constant if possible
        defaultInfo = new DefaultInfoImpl(false, defaultNode.getDefaultText(), defaultValue);
        if (SanityManager.DEBUG) {
            /* Save the APL off in the constraint node */
            if (apl.size() > 0) {
                SanityManager.THROWASSERT("DEFAULT clause has unexpected dependencies");
            }
            // Restore the previous AuxiliaryProviderList
            cc.setCurrentAuxiliaryProviderList(prevAPL);
        }
    } finally {
        cc.setReliability(previousReliability);
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) List(java.util.List) ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Aggregations

TypeId (org.apache.derby.iapi.types.TypeId)53 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)32 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)8 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)6 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)4 UserDefinedTypeIdImpl (org.apache.derby.catalog.types.UserDefinedTypeIdImpl)3 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)3 StandardException (org.apache.derby.shared.common.error.StandardException)3 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)2 DefaultInfoImpl (org.apache.derby.catalog.types.DefaultInfoImpl)2 RoutineAliasInfo (org.apache.derby.catalog.types.RoutineAliasInfo)2 ClassInspector (org.apache.derby.iapi.services.loader.ClassInspector)2 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)2 ProviderList (org.apache.derby.iapi.sql.depend.ProviderList)2 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)2 JSQLType (org.apache.derby.iapi.types.JSQLType)2 ResultSet (java.sql.ResultSet)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Properties (java.util.Properties)1