Search in sources :

Example 61 with DataTypeDescriptor

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

the class TableElementList method setCollationTypeOnCharacterStringColumn.

/**
 * Use the passed schema descriptor's collation type to set the collation
 * of a character string column.
 * @param sd
 */
void setCollationTypeOnCharacterStringColumn(SchemaDescriptor sd, ColumnDefinitionNode cdn) throws StandardException {
    int collationType = sd.getCollationType();
    // 
    // Only generated columns can omit the datatype specification during the
    // early phases of binding--before we have been able to bind the
    // generation clause.
    // 
    DataTypeDescriptor dtd = cdn.getType();
    if (dtd == null) {
        if (!cdn.hasGenerationClause()) {
            throw StandardException.newException(SQLState.LANG_NEEDS_DATATYPE, cdn.getColumnName());
        }
    } else {
        if (dtd.getTypeId().isStringTypeId()) {
            cdn.setCollationType(collationType);
        }
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 62 with DataTypeDescriptor

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

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

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

Example 65 with DataTypeDescriptor

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

the class ResultColumn method columnTypeAndLengthMatch.

boolean columnTypeAndLengthMatch(ResultColumn otherColumn) throws StandardException {
    ValueNode otherExpression = otherColumn.getExpression();
    DataTypeDescriptor resultColumnType = getTypeServices();
    DataTypeDescriptor otherResultColumnType = otherColumn.getTypeServices();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(resultColumnType != null, "Type is null for column " + this);
        SanityManager.ASSERT(otherResultColumnType != null, "Type is null for column " + otherColumn);
    }
    /*
		** We can never make any assumptions about
		** parameters.  So don't even bother in this
		** case.
		*/
    if ((otherExpression != null) && (otherExpression.requiresTypeFromContext()) || (_expression.requiresTypeFromContext())) {
        return false;
    }
    // method in org.apache.derby.iapi.types.XML for more.
    if (resultColumnType.getTypeId().isXMLTypeId())
        return false;
    /* Are they the same type? */
    if (!resultColumnType.getTypeId().equals(otherResultColumnType.getTypeId())) {
        /* If the source is a constant of a different type then
			 * we try to convert that constant to a constant of our
			 * type. (The initial implementation only does the conversion
			 * to string types because the most common problem is a char
			 * constant with a varchar column.)  
			 * NOTE: We do not attempt any conversion here if the source
			 * is a string type and the target is not or vice versa in 
			 * order to avoid problems with implicit varchar conversions.
			 * Anyway, we will check if the "converted" constant has the
			 * same type as the original constant.  If not, then the conversion
			 * happened.  In that case, we will reuse the ConstantNode, for simplicity,
			 * and reset the type to match the desired type.
			 */
        if (otherExpression instanceof ConstantNode) {
            ConstantNode constant = (ConstantNode) otherColumn.getExpression();
            DataValueDescriptor oldValue = constant.getValue();
            DataValueDescriptor newValue = convertConstant(resultColumnType.getTypeId(), resultColumnType.getMaximumWidth(), oldValue);
            if ((oldValue != newValue) && (oldValue instanceof StringDataValue == newValue instanceof StringDataValue)) {
                constant.setValue(newValue);
                constant.setType(getTypeServices());
                otherColumn.bindResultColumnToExpression();
                otherResultColumnType = otherColumn.getType();
            }
            // depending on the collation type.
            if (newValue instanceof StringDataValue) {
                constant.setCollationInfo(resultColumnType);
                DataValueFactory dvf = getDataValueFactory();
                newValue = ((StringDataValue) newValue).getValue(dvf.getCharacterCollator(constant.getTypeServices().getCollationType()));
                constant.setValue(newValue);
            }
        }
        if (!resultColumnType.getTypeId().equals(otherResultColumnType.getTypeId())) {
            return false;
        }
    }
    /* Are they the same precision? */
    if (resultColumnType.getPrecision() != otherResultColumnType.getPrecision()) {
        return false;
    }
    /* Are they the same scale? */
    if (resultColumnType.getScale() != otherResultColumnType.getScale()) {
        return false;
    }
    /* Are they the same width? */
    if (resultColumnType.getMaximumWidth() != otherResultColumnType.getMaximumWidth()) {
        return false;
    }
    /* Is the source nullable and the target non-nullable? 
		 * The source is nullable if it is nullable or if the target is generated
		 * for an unmatched column in an insert with a column list.
		 * This additional check is needed because when we generate any additional
		 * source RCs for an insert with a column list the generated RCs for any 
		 * non-specified columns get the type info from the column.  Thus, 
		 * for t1(non_nullable, nullable)
		 *	insert into t2 (nullable) values 1;
		 * RCType.isNullable() returns false for the generated source RC for 
		 * non_nullable.  In this case, we want to see it as
		 */
    if ((!resultColumnType.isNullable()) && (otherResultColumnType.isNullable() || otherColumn.isGeneratedForUnmatchedColumnInInsert())) {
        return false;
    }
    return true;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) DataValueFactory(org.apache.derby.iapi.types.DataValueFactory) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) StringDataValue(org.apache.derby.iapi.types.StringDataValue)

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