Search in sources :

Example 31 with TypeId

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

the class TableElementList method bindAndValidateGenerationClauses.

/**
 * Bind and validate all of the generation clauses in this list against
 * the specified FromList.
 *
 * @param sd			Schema where the table lives.
 * @param fromList		The FromList in question.
 * @param generatedColumns Bitmap of generated columns in the table. Vacuous for CREATE TABLE, but may be non-trivial for ALTER TABLE. This routine may set bits for new generated columns.
 * @param baseTable  Table descriptor if this is an ALTER TABLE statement.
 *
 * @exception StandardException		Thrown on error
 */
void bindAndValidateGenerationClauses(SchemaDescriptor sd, FromList fromList, FormatableBitSet generatedColumns, TableDescriptor baseTable) throws StandardException {
    FromBaseTable table = (FromBaseTable) fromList.elementAt(0);
    ResultColumnList tableColumns = table.getResultColumns();
    int columnCount = table.getResultColumns().size();
    // complain if a generation clause references another generated column
    findIllegalGenerationReferences(fromList, baseTable);
    generatedColumns.grow(columnCount + 1);
    CompilerContext cc = getCompilerContext();
    ArrayList<AggregateNode> aggregates = new ArrayList<AggregateNode>();
    for (TableElementNode element : this) {
        ColumnDefinitionNode cdn;
        GenerationClauseNode generationClauseNode;
        ValueNode generationTree;
        if (!(element instanceof ColumnDefinitionNode)) {
            continue;
        }
        cdn = (ColumnDefinitionNode) element;
        if (!cdn.hasGenerationClause()) {
            continue;
        }
        generationClauseNode = cdn.getGenerationClauseNode();
        // bind the generation clause
        final int previousReliability = cc.getReliability();
        ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();
        try {
            /* Each generation clause can have its own set of dependencies.
				 * These dependencies need to be shared with the prepared
				 * statement as well.  We create a new auxiliary provider list
				 * for the generation clause, "push" it on the compiler context
				 * by swapping it with the current auxiliary provider list
				 * and the "pop" it when we're done by restoring the old 
				 * auxiliary provider list.
				 */
            ProviderList apl = new ProviderList();
            cc.setCurrentAuxiliaryProviderList(apl);
            // Tell the compiler context to forbid subqueries and
            // non-deterministic functions.
            cc.setReliability(CompilerContext.GENERATION_CLAUSE_RESTRICTION);
            generationTree = generationClauseNode.bindExpression(fromList, (SubqueryList) null, aggregates);
            SelectNode.checkNoWindowFunctions(generationClauseNode, "generation clause");
            // 
            // If the user did not declare a type for this column, then the column type defaults
            // to the type of the generation clause.
            // However, if the user did declare a type for this column, then the
            // type of the generation clause must be assignable to the declared
            // type.
            // 
            DataTypeDescriptor generationClauseType = generationTree.getTypeServices();
            DataTypeDescriptor declaredType = cdn.getType();
            if (declaredType == null) {
                cdn.setType(generationClauseType);
                // 
                // Poke the type into the FromTable so that constraints will
                // compile.
                // 
                tableColumns.getResultColumn(cdn.getColumnName(), false).setType(generationClauseType);
                // 
                // We skipped these steps earlier on because we didn't have
                // a datatype. Now that we have a datatype, revisit these
                // steps.
                // 
                setCollationTypeOnCharacterStringColumn(sd, cdn);
                cdn.checkUserType(table.getTableDescriptor());
            } else {
                TypeId declaredTypeId = declaredType.getTypeId();
                TypeId resolvedTypeId = generationClauseType.getTypeId();
                if (!getTypeCompiler(resolvedTypeId).convertible(declaredTypeId, false)) {
                    throw StandardException.newException(SQLState.LANG_UNASSIGNABLE_GENERATION_CLAUSE, cdn.getName(), resolvedTypeId.getSQLTypeName());
                }
            }
            // no aggregates, please
            if (!aggregates.isEmpty()) {
                throw StandardException.newException(SQLState.LANG_AGGREGATE_IN_GENERATION_CLAUSE, cdn.getName());
            }
            /* Save the APL off in the constraint node */
            if (apl.size() > 0) {
                generationClauseNode.setAuxiliaryProviderList(apl);
            }
        } finally {
            // Restore previous compiler state
            cc.setCurrentAuxiliaryProviderList(prevAPL);
            cc.setReliability(previousReliability);
        }
        /* We have a valid generation clause, now build an array of
			 * 1-based columnIds that the clause references.
			 */
        ResultColumnList rcl = table.getResultColumns();
        int numReferenced = rcl.countReferencedColumns();
        int[] generationClauseColumnReferences = new int[numReferenced];
        int position = rcl.getPosition(cdn.getColumnName(), 1);
        generatedColumns.set(position);
        rcl.recordColumnReferences(generationClauseColumnReferences, 1);
        String[] referencedColumnNames = new String[numReferenced];
        for (int i = 0; i < numReferenced; i++) {
            referencedColumnNames[i] = rcl.elementAt(generationClauseColumnReferences[i] - 1).getName();
        }
        String currentSchemaName = getLanguageConnectionContext().getCurrentSchemaName();
        DefaultInfoImpl dii = new DefaultInfoImpl(generationClauseNode.getExpressionText(), referencedColumnNames, currentSchemaName);
        cdn.setDefaultInfo(dii);
        /* Clear the column references in the RCL so each generation clause
			 * starts with a clean list.
			 */
        rcl.clearColumnReferences();
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) ArrayList(java.util.ArrayList) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Example 32 with TypeId

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

the class UnaryArithmeticOperatorNode method bindSQRTABS.

/**
 * Bind SQRT or ABS
 *
 * @exception StandardException		Thrown on error
 */
private void bindSQRTABS() throws StandardException {
    TypeId operandType;
    int jdbcType;
    /*
		** Check the type of the operand 
		*/
    operandType = operand.getTypeId();
    /*
	 	 * If the operand is not a build-in type, generate a bound conversion
		 * tree to build-in types.
		 */
    if (operandType.userType()) {
        operand = operand.genSQLJavaSQLTree();
    }
    /* DB2 doesn't cast string types to numeric types for numeric functions  */
    jdbcType = operandType.getJDBCTypeId();
    /* Both SQRT and ABS are only allowed on numeric types */
    if (!operandType.isNumericTypeId())
        throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, getOperatorString(), operandType.getSQLTypeName());
    /* For SQRT, if operand is not a DOUBLE, convert it to DOUBLE */
    if (kind == K_SQRT && jdbcType != Types.DOUBLE) {
        operand = new CastNode(operand, new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.DOUBLE), true), getContextManager());
        ((CastNode) operand).bindCastNodeOnly();
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 33 with TypeId

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

the class UnaryOperatorNode method bindXMLSerialize.

/**
 * Bind an XMLSERIALIZE operator.  Makes sure the operand type
 * and target type are both correct, and sets the result type.
 *
 * @exception StandardException Thrown on error
 */
private void bindXMLSerialize() throws StandardException {
    TypeId operandType;
    // Check the type of the operand - this function is allowed only on
    // the XML type.
    operandType = operand.getTypeId();
    if ((operandType != null) && !operandType.isXMLTypeId()) {
        throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, methodName, operandType.getSQLTypeName());
    }
    // it from there.
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT((targetType != null), "Failed to locate target type for XMLSERIALIZE operator");
    }
    TypeId targetTypeId = targetType.getTypeId();
    switch(targetTypeId.getJDBCTypeId()) {
        case Types.CHAR:
        case Types.VARCHAR:
        case Types.LONGVARCHAR:
        case Types.CLOB:
            break;
        default:
            {
                throw StandardException.newException(SQLState.LANG_INVALID_XMLSERIALIZE_TYPE, targetTypeId.getSQLTypeName());
            }
    }
    // The result type of XMLSerialize() is always a string; which
    // kind of string is determined by the targetType field.
    setType(targetType);
    // Set the collation type to be same as the current schema's
    // collation type.
    setCollationUsingCompilationSchema();
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId)

Example 34 with TypeId

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

the class UnaryOperatorNode method bindXMLParse.

/**
 * Bind an XMLPARSE operator.  Makes sure the operand type
 * is correct, and sets the result type.
 *
 * @exception StandardException Thrown on error
 */
private void bindXMLParse() throws StandardException {
    // Check the type of the operand - this function is allowed only on
    // string value (char) types.
    TypeId operandType = operand.getTypeId();
    if (operandType != null) {
        switch(operandType.getJDBCTypeId()) {
            case Types.CHAR:
            case Types.VARCHAR:
            case Types.LONGVARCHAR:
            case Types.CLOB:
                break;
            default:
                {
                    throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, methodName, operandType.getSQLTypeName());
                }
        }
    }
    // The result type of XMLParse() is always an XML type.
    setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SQLXML));
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId)

Example 35 with TypeId

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

the class SimpleStringOperatorNode method bindExpression.

/**
 * Bind this operator
 *
 * @param fromList			The query's FROM list
 * @param subqueryList		The subquery list being built as we find SubqueryNodes
 * @param aggregates        The aggregate list being built as we find AggregateNodes
 *
 * @return	The new top of the expression tree.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
    TypeId operandType;
    bindOperand(fromList, subqueryList, aggregates);
    /*
		** Check the type of the operand - this function is allowed only on
		** string value (char and bit) types.
		*/
    operandType = operand.getTypeId();
    switch(operandType.getJDBCTypeId()) {
        case Types.CHAR:
        case Types.VARCHAR:
        case Types.LONGVARCHAR:
        case Types.CLOB:
            break;
        case Types.JAVA_OBJECT:
        case Types.OTHER:
            {
                throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, methodName, operandType.getSQLTypeName());
            }
        default:
            DataTypeDescriptor dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.VARCHAR, true, operand.getTypeCompiler().getCastToCharWidth(operand.getTypeServices()));
            operand = new CastNode(operand, dtd, getContextManager());
            // DERBY-2910 - Match current schema collation for implicit cast as we do for
            // explicit casts per SQL Spec 6.12 (10)
            operand.setCollationUsingCompilationSchema();
            ((CastNode) operand).bindCastNodeOnly();
            operandType = operand.getTypeId();
    }
    /*
		** The result type of upper()/lower() is the type of the operand.
		*/
    setType(new DataTypeDescriptor(operandType, operand.getTypeServices().isNullable(), operand.getTypeCompiler().getCastToCharWidth(operand.getTypeServices())));
    // Result of upper()/lower() will have the same collation as the
    // argument to upper()/lower().
    setCollationInfo(operand.getTypeServices());
    return this;
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

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