Search in sources :

Example 6 with ProviderList

use of org.apache.derby.iapi.sql.depend.ProviderList in project derby by apache.

the class TableElementList method bindAndValidateCheckConstraints.

/**
 * Bind and validate all of the check constraints in this list against
 * the specified FromList.
 *
 * @param fromList		The FromList in question.
 *
 * @exception StandardException		Thrown on error
 */
void bindAndValidateCheckConstraints(FromList fromList) throws StandardException {
    FromBaseTable table = (FromBaseTable) fromList.elementAt(0);
    CompilerContext cc = getCompilerContext();
    ArrayList<AggregateNode> aggregates = new ArrayList<AggregateNode>();
    for (TableElementNode element : this) {
        ConstraintDefinitionNode cdn;
        ValueNode checkTree;
        if (!(element instanceof ConstraintDefinitionNode)) {
            continue;
        }
        cdn = (ConstraintDefinitionNode) element;
        if (cdn.getConstraintType() != DataDictionary.CHECK_CONSTRAINT) {
            continue;
        }
        checkTree = cdn.getCheckCondition();
        // bind the check condition
        // verify that it evaluates to a boolean
        final int previousReliability = cc.getReliability();
        try {
            /* Each check constraint 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 check constraint, "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();
            ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();
            cc.setCurrentAuxiliaryProviderList(apl);
            // Tell the compiler context to only allow deterministic nodes
            cc.setReliability(CompilerContext.CHECK_CONSTRAINT);
            checkTree = checkTree.bindExpression(fromList, (SubqueryList) null, aggregates);
            // no aggregates, please
            if (!aggregates.isEmpty()) {
                throw StandardException.newException(SQLState.LANG_INVALID_CHECK_CONSTRAINT, cdn.getConstraintText());
            }
            checkTree = checkTree.checkIsBoolean();
            cdn.setCheckCondition(checkTree);
            /* Save the APL off in the constraint node */
            if (apl.size() > 0) {
                cdn.setAuxiliaryProviderList(apl);
            }
            // Restore the previous AuxiliaryProviderList
            cc.setCurrentAuxiliaryProviderList(prevAPL);
        } finally {
            cc.setReliability(previousReliability);
        }
        /* We have a valid check constraint.
             * Now we build a list with only the referenced columns and
			 * copy it to the cdn.  Thus we can build the array of
			 * column names for the referenced columns during generate().
			 */
        ResultColumnList rcl = table.getResultColumns();
        int numReferenced = rcl.countReferencedColumns();
        ResultColumnList refRCL = new ResultColumnList(getContextManager());
        rcl.copyReferencedColumnsToNewList(refRCL);
        /* A column check constraint can only refer to that column. If this is a
			 * column constraint, we should have an RCL with that column
			 */
        if (cdn.getColumnList() != null) {
            String colName = cdn.getColumnList().elementAt(0).getName();
            if (numReferenced > 1 || !colName.equals(refRCL.elementAt(0).getName()))
                throw StandardException.newException(SQLState.LANG_DB2_INVALID_CHECK_CONSTRAINT, colName);
        }
        cdn.setColumnList(refRCL);
        /* Clear the column references in the RCL so each check constraint
			 * starts with a clean list.
			 */
        rcl.clearColumnReferences();
        // Make sure all names are schema qualified (DERBY-6362)
        cdn.qualifyNames();
    }
}
Also used : ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) ArrayList(java.util.ArrayList)

Example 7 with ProviderList

use of org.apache.derby.iapi.sql.depend.ProviderList 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 8 with ProviderList

use of org.apache.derby.iapi.sql.depend.ProviderList in project derby by apache.

the class CreateViewNode method bindViewDefinition.

/**
 * Bind the query expression for a view definition.
 *
 * @param dataDictionary	The DataDictionary to use to look up
 *				columns, tables, etc.
 *
 * @return	Array of providers that this view depends on.
 *
 * @exception StandardException		Thrown on error
 */
private ProviderInfo[] bindViewDefinition(DataDictionary dataDictionary, CompilerContext compilerContext, LanguageConnectionContext lcc, OptimizerFactory optimizerFactory, ResultSetNode queryExpr, ContextManager cm) throws StandardException {
    FromList fromList = new FromList(optimizerFactory.doJoinOrderOptimization(), cm);
    ProviderList prevAPL = compilerContext.getCurrentAuxiliaryProviderList();
    ProviderList apl = new ProviderList();
    try {
        compilerContext.setCurrentAuxiliaryProviderList(apl);
        compilerContext.pushCurrentPrivType(Authorizer.SELECT_PRIV);
        /* Bind the tables in the queryExpression */
        queryExpr = queryExpr.bindNonVTITables(dataDictionary, fromList);
        queryExpr = queryExpr.bindVTITables(fromList);
        /* Bind the expressions under the resultSet */
        queryExpr.bindExpressions(fromList);
        // cannot define views on temporary tables
        if (queryExpr instanceof SelectNode) {
            // If attempting to reference a SESSION schema table (temporary or permanent) in the view, throw an exception
            if (queryExpr.referencesSessionSchema())
                throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
        }
        // bind the query expression
        queryExpr.bindResultColumns(fromList);
        // rejects any untyped nulls in the RCL
        // e.g.:  CREATE VIEW v1 AS VALUES NULL
        queryExpr.bindUntypedNullsToResultColumns(null);
    } finally {
        compilerContext.popCurrentPrivType();
        compilerContext.setCurrentAuxiliaryProviderList(prevAPL);
    }
    DependencyManager dm = dataDictionary.getDependencyManager();
    ProviderInfo[] provInfo = dm.getPersistentProviderInfos(apl);
    // need to clear the column info in case the same table descriptor
    // is reused, eg., in multiple target only view definition
    dm.clearColumnInfoInProviders(apl);
    /* Verify that all underlying ResultSets reclaimed their FromList */
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(fromList.size() == 0, "fromList.size() is expected to be 0, not " + fromList.size() + " on return from RS.bindExpressions()");
    }
    return provInfo;
}
Also used : ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) ProviderInfo(org.apache.derby.iapi.sql.depend.ProviderInfo) DependencyManager(org.apache.derby.iapi.sql.depend.DependencyManager)

Aggregations

ProviderList (org.apache.derby.iapi.sql.depend.ProviderList)8 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)5 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)4 ArrayList (java.util.ArrayList)3 ProviderInfo (org.apache.derby.iapi.sql.depend.ProviderInfo)3 DefaultInfoImpl (org.apache.derby.catalog.types.DefaultInfoImpl)2 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)2 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)2 TypeId (org.apache.derby.iapi.types.TypeId)2 HashSet (java.util.HashSet)1 List (java.util.List)1 UUID (org.apache.derby.catalog.UUID)1 ContextManager (org.apache.derby.iapi.services.context.ContextManager)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)1 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)1 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)1 ColumnInfo (org.apache.derby.impl.sql.execute.ColumnInfo)1 ConstraintInfo (org.apache.derby.impl.sql.execute.ConstraintInfo)1 IndexConstantAction (org.apache.derby.impl.sql.execute.IndexConstantAction)1