Search in sources :

Example 21 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class CreateTriggerNode method bindStatement.

// accessors
// We inherit the generate() method from DDLStatementNode.
/**
 * Bind this CreateTriggerNode.  This means doing any static error
 * checking that can be done before actually creating the table.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    CompilerContext compilerContext = getCompilerContext();
    DataDictionary dd = getDataDictionary();
    /*
		** Grab the current schema.  We will use that for
		** sps compilation
		*/
    LanguageConnectionContext lcc = getLanguageConnectionContext();
    compSchemaDescriptor = lcc.getDefaultSchema();
    /*
		** Get and check the schema descriptor for this
		** trigger.  This check will throw the proper exception
		** if someone tries to create a trigger in the SYS
		** schema.
		*/
    triggerSchemaDescriptor = getSchemaDescriptor();
    /*
		** Get the trigger table.
		*/
    triggerTableDescriptor = getTableDescriptor(tableName);
    // throw an exception if user is attempting to create a trigger on a temporary table
    if (isSessionSchema(triggerTableDescriptor.getSchemaDescriptor())) {
        throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
    }
    if (isPrivilegeCollectionRequired()) {
        compilerContext.pushCurrentPrivType(Authorizer.TRIGGER_PRIV);
        compilerContext.addRequiredTablePriv(triggerTableDescriptor);
        compilerContext.popCurrentPrivType();
    }
    /*
		** Regenerates the actionText and actionNode if necessary.
		*/
    boolean needInternalSQL = bindReferencesClause(dd);
    // Get all the names of SQL objects referenced by the triggered
    // SQL statement and the WHEN clause. Since some of the TableName
    // nodes may be eliminated from the node tree during the bind phase,
    // we collect the nodes before the nodes have been bound. The
    // names will be used later when we normalize the trigger text
    // that will be stored in the system tables.
    SortedSet<TableName> actionNames = actionNode.getOffsetOrderedNodes(TableName.class);
    SortedSet<TableName> whenNames = (whenClause != null) ? whenClause.getOffsetOrderedNodes(TableName.class) : null;
    ProviderList prevAPL = compilerContext.getCurrentAuxiliaryProviderList();
    ProviderList apl = new ProviderList();
    lcc.pushTriggerTable(triggerTableDescriptor);
    try {
        compilerContext.setCurrentAuxiliaryProviderList(apl);
        /*
			** Bind the trigger action and the trigger
			** when clause to make sure that they are
			** ok.  Note that we have already substituted 
			** in various replacements for OLD/NEW transition
			** tables/variables and reparsed if necessary.
			*/
        if (needInternalSQL)
            compilerContext.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);
        // bind of the call statement node.
        if (isBefore)
            compilerContext.setReliability(CompilerContext.MODIFIES_SQL_DATA_PROCEDURE_ILLEGAL);
        actionNode.bindStatement();
        if (whenClause != null) {
            ContextManager cm = getContextManager();
            whenClause = whenClause.bindExpression(new FromList(cm), new SubqueryList(cm), new ArrayList<AggregateNode>(0));
            // The WHEN clause must be a BOOLEAN expression.
            whenClause.checkIsBoolean();
        }
    } finally {
        lcc.popTriggerTable(triggerTableDescriptor);
        compilerContext.setCurrentAuxiliaryProviderList(prevAPL);
    }
    // Qualify identifiers before storing them (DERBY-5901/DERBY-6370).
    qualifyNames(actionNames, whenNames);
    /* 
		** Statement is dependent on the TableDescriptor 
		*/
    compilerContext.createDependency(triggerTableDescriptor);
    /*
		** If there is a list of columns, then no duplicate columns,
		** and all columns must be found.
		*/
    if (triggerCols != null && triggerCols.size() != 0) {
        HashSet<String> columnNames = new HashSet<String>();
        for (ResultColumn rc : triggerCols) {
            if (!columnNames.add(rc.getName())) {
                throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_IN_TRIGGER_UPDATE, rc.getName(), triggerName);
            }
            ColumnDescriptor cd = triggerTableDescriptor.getColumnDescriptor(rc.getName());
            if (cd == null) {
                throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, rc.getName(), tableName);
            }
        }
    }
    // statement references a table in the SESSION schema.
    if (referencesSessionSchema()) {
        throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
    }
    DependencyManager dm = dd.getDependencyManager();
    providerInfo = dm.getPersistentProviderInfos(apl);
    dm.clearColumnInfoInProviders(apl);
}
Also used : ProviderList(org.apache.derby.iapi.sql.depend.ProviderList) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) ArrayList(java.util.ArrayList) DependencyManager(org.apache.derby.iapi.sql.depend.DependencyManager) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) ContextManager(org.apache.derby.iapi.services.context.ContextManager) HashSet(java.util.HashSet)

Example 22 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class CursorNode method bindStatement.

/**
 * Bind this CursorNode.  This means looking up tables and columns and
 * getting their types, and figuring out the result types of all
 * expressions, as well as doing view resolution, permissions checking,
 * etc. It also includes determining whether an UNSPECIFIED cursor
 * is updatable or not, and verifying that an UPDATE cursor actually is.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    // 
    // Don't add USAGE privilege on user-defined types.
    // 
    boolean wasSkippingTypePrivileges = getCompilerContext().skipTypePrivileges(true);
    DataDictionary dataDictionary;
    dataDictionary = getDataDictionary();
    checkIndexStats = (dataDictionary.getIndexStatsRefresher(true) != null);
    // will be returned (see genProjectRestrict() in SelectNode.java).
    if (orderByList != null) {
        orderByList.pullUpOrderByColumns(resultSet);
    }
    getCompilerContext().pushCurrentPrivType(getPrivType());
    try {
        FromList fromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
        /* Check for ? parameters directly under the ResultColums */
        resultSet.rejectParameters();
        super.bind(dataDictionary);
        // bind the query expression
        resultSet.bindResultColumns(fromList);
        // this rejects any untyped nulls in the select list
        // pass in null to indicate that we don't have any
        // types for this node
        resultSet.bindUntypedNullsToResultColumns(null);
        // define how we bind these out, so we don't allow it.
        if (!forMergeStatement) {
            resultSet.rejectXMLValues();
        }
        /* 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()");
        }
    } finally {
        getCompilerContext().popCurrentPrivType();
    }
    // Collect tables whose indexes we'll want to check for staleness.
    collectTablesWithPossiblyStaleStats();
    // bind the order by
    if (orderByList != null) {
        orderByList.bindOrderByColumns(resultSet);
    }
    bindOffsetFetch(offset, fetchFirst);
    // if it says it is updatable, verify it.
    if (updateMode == UPDATE) {
        int checkedUpdateMode;
        checkedUpdateMode = determineUpdateMode(dataDictionary);
        if (SanityManager.DEBUG)
            SanityManager.DEBUG("DumpUpdateCheck", "update mode is UPDATE (" + updateMode + ") checked mode is " + checkedUpdateMode);
        if (updateMode != checkedUpdateMode)
            throw StandardException.newException(SQLState.LANG_STMT_NOT_UPDATABLE);
    }
    // if it doesn't know if it is updatable, determine it
    if (updateMode == UNSPECIFIED) {
        if (getLanguageConnectionContext().getStatementContext().isForReadOnly()) {
            updateMode = READ_ONLY;
        } else {
            updateMode = determineUpdateMode(dataDictionary);
        }
    // if (SanityManager.DEBUG)
    // SanityManager.DEBUG("DumpUpdateCheck","update mode is UNSPECIFIED ("+UNSPECIFIED+") checked mode is "+updateMode);
    }
    if (updateMode == READ_ONLY) {
        // don't need them any more
        updatableColumns = null;
    }
    // bind the update columns
    if (updateMode == UPDATE) {
        bindUpdateColumns(updateTable);
        // columns.
        if (updateTable != null) {
            updateTable.markUpdatableByCursor(updatableColumns);
            // make sure that alongwith the FromTable, we keep other ResultSetLists
            // in correct state too. ResultSetMetaData.isWritable looks at this to
            // return the correct value.
            resultSet.getResultColumns().markColumnsInSelectListUpdatableByCursor(updatableColumns);
        }
    }
    resultSet.renameGeneratedResultNames();
    // need to look for SESSION tables only if global temporary tables declared for the connection
    if (getLanguageConnectionContext().checkIfAnyDeclaredGlobalTempTablesForThisConnection()) {
        // If this cursor has references to session schema tables, save the names of those tables into compiler context
        // so they can be passed to execution phase.
        ArrayList<String> sessionSchemaTableNames = getSessionSchemaTableNamesForCursor();
        if (sessionSchemaTableNames != null)
            indexOfSessionTableNamesInSavedObjects = getCompilerContext().addSavedObject(sessionSchemaTableNames);
    }
    getCompilerContext().skipTypePrivileges(wasSkippingTypePrivileges);
}
Also used : DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 23 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class DMLModStatementNode method verifyTargetTable.

/**
 * Verify the target table.  Get the TableDescriptor
 * if the target table is not a VTI.
 *
 * @exception StandardException		Thrown on error
 */
void verifyTargetTable() throws StandardException {
    DataDictionary dataDictionary = getDataDictionary();
    if (targetTableName != null) {
        /*
			** Get the TableDescriptor for the table we are inserting into
			*/
        SchemaDescriptor sdtc = getSchemaDescriptor(targetTableName.getSchemaName());
        targetTableDescriptor = getTableDescriptor(targetTableName.getTableName(), sdtc);
        if (targetTableDescriptor == null) {
            // Check if the reference is for a synonym.
            TableName synonymTab = resolveTableToSynonym(targetTableName);
            if (synonymTab == null)
                throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName);
            synonymTableName = targetTableName;
            targetTableName = synonymTab;
            sdtc = getSchemaDescriptor(targetTableName.getSchemaName());
            targetTableDescriptor = getTableDescriptor(synonymTab.getTableName(), sdtc);
            if (targetTableDescriptor == null)
                throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, targetTableName);
        }
        targetTableName.setSchemaName(sdtc.getSchemaName());
        switch(targetTableDescriptor.getTableType()) {
            case TableDescriptor.VIEW_TYPE:
                // Views are currently not updatable
                throw StandardException.newException(SQLState.LANG_VIEW_NOT_UPDATEABLE, targetTableName);
            case TableDescriptor.VTI_TYPE:
            // fall through - currently all vti tables are system tables.
            case TableDescriptor.SYSTEM_TABLE_TYPE:
                // System tables are not updatable
                throw StandardException.newException(SQLState.LANG_UPDATE_SYSTEM_TABLE_ATTEMPTED, targetTableName);
            default:
                break;
        }
        /* We need to get some kind of table lock (IX here), to prevent
			 * another thread from adding a new index while we are binding,
			 * if we are a reader in DDL mode.  Just a row lock on system table
			 * SYSCONGLOMERATE is not enough: that wouldn't prevent another
			 * thread from adding a new entry.  Part of the fix for Beetle 3976.
			 * Same lock as in exec, compatible with row lock, for concurrency.
			 */
        targetTableDescriptor = lockTableForCompilation(targetTableDescriptor);
        getCompilerContext().createDependency(targetTableDescriptor);
    } else {
        /* VTI - VTIs in DML Mod are version 2 VTIs - They
			 * must implement java.sql.PreparedStatement and have
			 * the JDBC2.0 getMetaData() and getResultSetConcurrency()
			 * methods and return an updatable ResultSet.
			 */
        FromList dummyFromList = new FromList(getContextManager());
        targetVTI = (FromVTI) targetVTI.bindNonVTITables(dataDictionary, dummyFromList);
        targetVTI = (FromVTI) targetVTI.bindVTITables(dummyFromList);
    }
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 24 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class GroupByNode method addAggregateColumns.

/**
 * In the query rewrite involving aggregates, add the columns for
 * aggregation.
 *
 * @see #addNewColumnsForAggregation
 */
private void addAggregateColumns() throws StandardException {
    DataDictionary dd = getDataDictionary();
    ColumnReference newColumnRef;
    ResultColumn newRC;
    ResultColumn tmpRC;
    ResultColumn aggResultRC;
    ResultColumnList bottomRCL = childResult.getResultColumns();
    ResultColumnList groupByRCL = getResultColumns();
    ResultColumnList aggRCL;
    int aggregatorVColId;
    int aggInputVColId;
    int aggResultVColId;
    /*
		 ** Now process all of the aggregates.  Replace
		 ** every aggregate with an RC.  We toss out
		 ** the list of RCs, we need to get each RC
		 ** as we process its corresponding aggregate.
		 */
    LanguageFactory lf = getLanguageConnectionContext().getLanguageFactory();
    ReplaceAggregatesWithCRVisitor replaceAggsVisitor = new ReplaceAggregatesWithCRVisitor(new ResultColumnList((getContextManager())), ((FromTable) childResult).getTableNumber(), ResultSetNode.class);
    parent.getResultColumns().accept(replaceAggsVisitor);
    if (havingClause != null) {
        // replace aggregates in the having clause with column references.
        replaceAggsVisitor = new ReplaceAggregatesWithCRVisitor(new ResultColumnList((getContextManager())), ((FromTable) childResult).getTableNumber());
        havingClause.accept(replaceAggsVisitor);
        // make having clause a restriction list in the parent
        // project restrict node.
        ProjectRestrictNode parentPRSN = (ProjectRestrictNode) parent;
        parentPRSN.setRestriction(havingClause);
    }
    /*
		** For each aggregate
		*/
    int alSize = aggregates.size();
    for (int index = 0; index < alSize; index++) {
        AggregateNode aggregate = aggregates.get(index);
        /*
			** AGG RESULT: Set the aggregate result to null in the
			** bottom project restrict.
			*/
        newRC = new ResultColumn("##aggregate result", aggregate.getNewNullResultExpression(), getContextManager());
        newRC.markGenerated();
        newRC.bindResultColumnToExpression();
        bottomRCL.addElement(newRC);
        newRC.setVirtualColumnId(bottomRCL.size());
        aggResultVColId = newRC.getVirtualColumnId();
        /*
			** Set the GB aggregrate result column to
			** point to this.  The GB aggregate result
			** was created when we called
			** ReplaceAggregatesWithCRVisitor()
			*/
        newColumnRef = new ColumnReference(newRC.getName(), null, getContextManager());
        newColumnRef.setSource(newRC);
        newColumnRef.setNestingLevel(this.getLevel());
        newColumnRef.setSourceLevel(this.getLevel());
        tmpRC = new ResultColumn(newRC.getColumnName(), newColumnRef, getContextManager());
        tmpRC.markGenerated();
        tmpRC.bindResultColumnToExpression();
        groupByRCL.addElement(tmpRC);
        tmpRC.setVirtualColumnId(groupByRCL.size());
        /*
			** Set the column reference to point to
			** this.
			*/
        newColumnRef = aggregate.getGeneratedRef();
        newColumnRef.setSource(tmpRC);
        /*
			** AGG INPUT: Create a ResultColumn in the bottom 
			** project restrict that has the expression that is
			** to be aggregated
			*/
        newRC = aggregate.getNewExpressionResultColumn(dd);
        newRC.markGenerated();
        newRC.bindResultColumnToExpression();
        bottomRCL.addElement(newRC);
        newRC.setVirtualColumnId(bottomRCL.size());
        aggInputVColId = newRC.getVirtualColumnId();
        aggResultRC = new ResultColumn("##aggregate expression", aggregate.getNewNullResultExpression(), getContextManager());
        /*
			** Add a reference to this column into the
			** group by columns.
			*/
        tmpRC = getColumnReference(newRC, dd);
        groupByRCL.addElement(tmpRC);
        tmpRC.setVirtualColumnId(groupByRCL.size());
        /*
			** AGGREGATOR: Add a getAggregator method call 
			** to the bottom result column list.
			*/
        newRC = aggregate.getNewAggregatorResultColumn(dd);
        newRC.markGenerated();
        newRC.bindResultColumnToExpression();
        bottomRCL.addElement(newRC);
        newRC.setVirtualColumnId(bottomRCL.size());
        aggregatorVColId = newRC.getVirtualColumnId();
        /*
			** Add a reference to this column in the Group By result
			** set.
			*/
        tmpRC = getColumnReference(newRC, dd);
        groupByRCL.addElement(tmpRC);
        tmpRC.setVirtualColumnId(groupByRCL.size());
        /*
			** Piece together a fake one column rcl that we will use
			** to generate a proper result description for input
			** to this agg if it is a user agg.
			*/
        aggRCL = new ResultColumnList((getContextManager()));
        aggRCL.addElement(aggResultRC);
        /*
			** Note that the column ids in the row are 0 based
			** so we have to subtract 1.
			*/
        aggInfo.addElement(new AggregatorInfo(aggregate.getAggregateName(), aggregate.getAggregatorClassName(), // aggregate input column
        aggInputVColId - 1, // the aggregate result column
        aggResultVColId - 1, // the aggregator column
        aggregatorVColId - 1, aggregate.isDistinct(), lf.getResultDescription(aggRCL.makeResultDescriptors(), "SELECT")));
    }
}
Also used : AggregatorInfo(org.apache.derby.impl.sql.execute.AggregatorInfo) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) LanguageFactory(org.apache.derby.iapi.sql.LanguageFactory)

Example 25 with DataDictionary

use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.

the class CallStatementNode method bindStatement.

/**
 * Bind this UpdateNode.  This means looking up tables and columns and
 * getting their types, and figuring out the result types of all
 * expressions, as well as doing view resolution, permissions checking,
 * etc.
 * <p>
 * Binding an update will also massage the tree so that
 * the ResultSetNode has a single column, the RID.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    DataDictionary dd = getDataDictionary();
    if (SanityManager.DEBUG)
        SanityManager.ASSERT((dd != null), "Failed to get data dictionary");
    SubqueryList subqueries = new SubqueryList(getContextManager());
    getCompilerContext().pushCurrentPrivType(getPrivType());
    methodCall = (JavaToSQLValueNode) methodCall.bindExpression(new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()), subqueries, null);
    // Don't allow sub-queries in CALL statements.
    if (subqueries.size() != 0) {
        throw StandardException.newException(SQLState.LANG_INVALID_CALL_STATEMENT);
    }
    // Disallow creation of BEFORE triggers which contain calls to
    // procedures that modify SQL data.
    checkReliability();
    getCompilerContext().popCurrentPrivType();
}
Also used : DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Aggregations

DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)102 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)57 TransactionController (org.apache.derby.iapi.store.access.TransactionController)40 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)33 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)23 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)22 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)17 StandardException (org.apache.derby.shared.common.error.StandardException)16 UUID (org.apache.derby.catalog.UUID)15 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)15 DataDescriptorGenerator (org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator)13 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)10 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)9 RoleGrantDescriptor (org.apache.derby.iapi.sql.dictionary.RoleGrantDescriptor)8 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)7 ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)7 ReferencedKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor)7 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)6 ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)6 Iterator (java.util.Iterator)5