Search in sources :

Example 1 with DefaultInfoImpl

use of org.apache.derby.catalog.types.DefaultInfoImpl in project derby by apache.

the class ResultSetNode method genNewRCForInsert.

/**
 * Generate the RC/expression for an unspecified column in an insert.
 * Use the default if one exists.
 *
 * @param targetTD			Target TableDescriptor if the target is not a VTI, null if a VTI.
 * @param targetVTI         Target description if it is a VTI, null if not a VTI
 * @param columnNumber		The column number
 * @param dataDictionary	The DataDictionary
 * @return	The RC/expression for the unspecified column.
 *
 * @exception StandardException		Thrown on error
 */
private ResultColumn genNewRCForInsert(TableDescriptor targetTD, FromVTI targetVTI, int columnNumber, DataDictionary dataDictionary) throws StandardException {
    ResultColumn newResultColumn;
    if (targetVTI != null) {
        newResultColumn = targetVTI.getResultColumns().getResultColumn(columnNumber);
        newResultColumn = newResultColumn.cloneMe();
        newResultColumn.setExpressionToNullNode();
    } else {
        // column position is 1-based, index is 0-based.
        ColumnDescriptor colDesc = targetTD.getColumnDescriptor(columnNumber);
        DataTypeDescriptor colType = colDesc.getType();
        // Check for defaults
        DefaultInfoImpl defaultInfo = (DefaultInfoImpl) colDesc.getDefaultInfo();
        // if it have defaultInfo and not be autoincrement.
        if (defaultInfo != null && !colDesc.isAutoincrement()) {
            // RESOLVEPARAMETER - skip the tree if we have the value
            /*
                  if (defaultInfo.getDefaultValue() != null)
                  {
                  }
                  else
                */
            {
                if (colDesc.hasGenerationClause()) {
                    // later on we will revisit the generated columns and bind
                    // their generation clauses
                    newResultColumn = createGeneratedColumn(targetTD, colDesc);
                } else {
                    // Generate the tree for the default
                    String defaultText = defaultInfo.getDefaultText();
                    ValueNode defaultTree = parseDefault(defaultText);
                    defaultTree = defaultTree.bindExpression(getFromList(), (SubqueryList) null, (List<AggregateNode>) null);
                    newResultColumn = new ResultColumn(defaultTree.getTypeServices(), defaultTree, getContextManager());
                }
                DefaultDescriptor defaultDescriptor = colDesc.getDefaultDescriptor(dataDictionary);
                if (SanityManager.DEBUG) {
                    SanityManager.ASSERT(defaultDescriptor != null, "defaultDescriptor expected to be non-null");
                }
                getCompilerContext().createDependency(defaultDescriptor);
            }
        } else if (colDesc.isAutoincrement()) {
            newResultColumn = new ResultColumn(colDesc, null, getContextManager());
            newResultColumn.setAutoincrementGenerated();
        } else {
            newResultColumn = new ResultColumn(colType, getNullNode(colType), getContextManager());
        }
    }
    // Mark the new RC as generated for an unmatched column in an insert
    newResultColumn.markGeneratedForUnmatchedColumnInInsert();
    return newResultColumn;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) DefaultDescriptor(org.apache.derby.iapi.sql.dictionary.DefaultDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Example 2 with DefaultInfoImpl

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

Example 3 with DefaultInfoImpl

use of org.apache.derby.catalog.types.DefaultInfoImpl 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 4 with DefaultInfoImpl

use of org.apache.derby.catalog.types.DefaultInfoImpl in project derby by apache.

the class ResultColumnList method replaceOrForbidDefaults.

/**
 * Replace any DEFAULTs with the associated tree for the default if
 * allowed, or flag.
 *
 * @param ttd	The TableDescriptor for the target table.
 * @param tcl	The RCL for the target table.
 * @param allowDefaults true if allowed
 *
 * @exception StandardException		Thrown on error
 */
void replaceOrForbidDefaults(TableDescriptor ttd, ResultColumnList tcl, boolean allowDefaults) throws StandardException {
    int size = size();
    for (int index = 0; index < size; index++) {
        ResultColumn rc = elementAt(index);
        if (rc.isDefaultColumn()) {
            if (!allowDefaults) {
                throw StandardException.newException(SQLState.LANG_INVALID_USE_OF_DEFAULT);
            }
            // DefaultNode defaultNode = (DefaultNode) rc.getExpression();
            // Get ColumnDescriptor by name or by position?
            ColumnDescriptor cd = null;
            if (tcl == null) {
                cd = ttd.getColumnDescriptor(index + 1);
            } else if (index < tcl.size()) {
                ResultColumn trc = tcl.elementAt(index);
                cd = ttd.getColumnDescriptor(trc.getName());
            }
            // Too many RCs if no ColumnDescriptor
            if (cd == null) {
                throw StandardException.newException(SQLState.LANG_TOO_MANY_RESULT_COLUMNS, ttd.getQualifiedName());
            }
            if (cd.isAutoincrement()) {
                rc.setAutoincrementGenerated();
            }
            // end of if ()
            DefaultInfoImpl defaultInfo = (DefaultInfoImpl) cd.getDefaultInfo();
            // 
            if ((defaultInfo != null) && !defaultInfo.isGeneratedColumn()) {
                setDefault(rc, cd, defaultInfo);
            } else {
                rc.setExpression(new UntypedNullConstantNode(getContextManager()));
                rc.setWasDefaultColumn(true);
            }
            rc.setDefaultColumn(false);
        }
    }
}
Also used : ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Example 5 with DefaultInfoImpl

use of org.apache.derby.catalog.types.DefaultInfoImpl in project derby by apache.

the class DefaultNode method bindExpression.

/**
 * Bind this expression.  This means binding the sub-expressions,
 * as well as figuring out what the return type is for this expression.
 * In this case, there are no sub-expressions, and the return type
 * is already known, so this is just a stub.
 *
 * @param fromList		The FROM list for the query this
 *				expression is in, for binding columns.
 * @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 failure
 */
@Override
ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
    ColumnDescriptor cd;
    TableDescriptor td;
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(fromList.size() != 0, "fromList expected to be non-empty");
        if (!(fromList.elementAt(0) instanceof FromBaseTable)) {
            SanityManager.THROWASSERT("fromList.elementAt(0) expected to be instanceof FromBaseTable, not " + fromList.elementAt(0).getClass().getName());
        }
    }
    // Get the TableDescriptor for the target table
    td = ((FromBaseTable) fromList.elementAt(0)).getTableDescriptor();
    // Get the ColumnDescriptor for the column
    cd = td.getColumnDescriptor(columnName);
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(cd != null, "cd expected to be non-null");
    }
    /* If we have the default text, then parse and bind it and
		 * return the tree.
		 */
    DefaultInfoImpl defaultInfo = (DefaultInfoImpl) cd.getDefaultInfo();
    if (defaultInfo != null) {
        String defaultTxt = defaultInfo.getDefaultText();
        ValueNode defaultTre = parseDefault(defaultTxt, getLanguageConnectionContext(), getCompilerContext());
        /* Query is dependent on the DefaultDescriptor */
        DefaultDescriptor defaultDescriptor = cd.getDefaultDescriptor(getDataDictionary());
        getCompilerContext().createDependency(defaultDescriptor);
        return defaultTre.bindExpression(fromList, subqueryList, aggregates);
    } else {
        // Default is null
        return new UntypedNullConstantNode(getContextManager());
    }
}
Also used : ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) DefaultDescriptor(org.apache.derby.iapi.sql.dictionary.DefaultDescriptor) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Aggregations

DefaultInfoImpl (org.apache.derby.catalog.types.DefaultInfoImpl)8 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)6 ResultColumnDescriptor (org.apache.derby.iapi.sql.ResultColumnDescriptor)4 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)3 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)2 ProviderList (org.apache.derby.iapi.sql.depend.ProviderList)2 DefaultDescriptor (org.apache.derby.iapi.sql.dictionary.DefaultDescriptor)2 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)2 TypeId (org.apache.derby.iapi.types.TypeId)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)1 UUID (org.apache.derby.catalog.UUID)1 UUIDFactory (org.apache.derby.iapi.services.uuid.UUIDFactory)1 DataDescriptorGenerator (org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator)1 UniqueTupleDescriptor (org.apache.derby.iapi.sql.dictionary.UniqueTupleDescriptor)1 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)1