Search in sources :

Example 1 with IgnoreFilter

use of org.apache.derby.iapi.sql.compile.IgnoreFilter in project derby by apache.

the class InsertNode method bindStatement.

/**
 * Bind this InsertNode.  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 insert will also massage the tree so that
 * the collist and select column order/number are the
 * same as the layout of the table in the store.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    // We just need select privilege on the expressions
    getCompilerContext().pushCurrentPrivType(Authorizer.SELECT_PRIV);
    FromList fromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
    /* If any underlying ResultSetNode is a SelectNode, then we
		 * need to do a full bind(), including the expressions
		 * (since the fromList may include a FromSubquery).
		 */
    DataDictionary dataDictionary = getDataDictionary();
    super.bindResultSetsWithTables(dataDictionary);
    /*
		** Get the TableDescriptor for the table we are inserting into
		*/
    verifyTargetTable();
    // Check the validity of the targetProperties, if they exist
    if (targetProperties != null) {
        verifyTargetProperties(dataDictionary);
    }
    /*
		** Get the resultColumnList representing the columns in the base
		** table or VTI. We don't bother adding any permission checks here
        ** because they are assumed by INSERT permission on the table.
		*/
    IgnoreFilter ignorePermissions = new IgnoreFilter();
    getCompilerContext().addPrivilegeFilter(ignorePermissions);
    getResultColumnList();
    /* If we have a target column list, then it must have the same # of
		 * entries as the result set's RCL.
		 */
    if (targetColumnList != null) {
        /*
			 * Normalize synonym qualifers for column references.
			 */
        if (synonymTableName != null) {
            normalizeSynonymColumns(targetColumnList, targetTableName);
        }
        /* Bind the target column list */
        getCompilerContext().pushCurrentPrivType(getPrivType());
        if (targetTableDescriptor != null) {
            targetColumnList.bindResultColumnsByName(targetTableDescriptor, (DMLStatementNode) this);
        } else {
            targetColumnList.bindResultColumnsByName(targetVTI.getResultColumns(), targetVTI, this);
        }
        getCompilerContext().popCurrentPrivType();
    }
    getCompilerContext().removePrivilegeFilter(ignorePermissions);
    /* 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()");
    }
    /* Replace any DEFAULTs with the associated tree, or flag DEFAULTs if
         * not allowed (inside top level set operator nodes). Subqueries are
         * checked for illegal DEFAULTs elsewhere.
         */
    boolean isTableConstructor = (resultSet instanceof UnionNode && ((UnionNode) resultSet).tableConstructor()) || resultSet instanceof RowResultSetNode;
    // 
    // For the MERGE statement, DEFAULT expressions in the SELECT node
    // may have been replaced with generated expressions already.
    // 
    ResultColumnList tempRCL = resultSet.getResultColumns();
    boolean defaultsWereReplaced = false;
    for (int i = 0; i < tempRCL.size(); i++) {
        ResultColumn rc = tempRCL.getResultColumn(i + 1);
        if (rc.wasDefaultColumn()) {
            defaultsWereReplaced = true;
        }
    }
    resultSet.replaceOrForbidDefaults(targetTableDescriptor, targetColumnList, isTableConstructor);
    /* Bind the expressions now that the result columns are bound 
		 * NOTE: This will be the 2nd time for those underlying ResultSets
		 * that have tables (no harm done), but it is necessary for those
		 * that do not have tables.  It's too hard/not work the effort to
		 * avoid the redundancy.
		 */
    super.bindExpressions();
    // 
    if (isPrivilegeCollectionRequired()) {
        getCompilerContext().pushCurrentPrivType(getPrivType());
        getCompilerContext().addRequiredTablePriv(targetTableDescriptor);
        getCompilerContext().popCurrentPrivType();
    }
    // Now stop adding permissions checks.
    getCompilerContext().addPrivilegeFilter(ignorePermissions);
    /*
		** If the result set is a union, it could be a table constructor.
		** Bind any nulls in the result columns of the table constructor
		** to the types of the table being inserted into.
		**
		** The types of ? parameters in row constructors and table constructors
		** in an INSERT statement come from the result columns.
		**
		** If there is a target column list, use that instead of the result
		** columns for the whole table, since the columns in the result set
		** correspond to the target column list.
		*/
    if (targetColumnList != null) {
        if (resultSet.getResultColumns().visibleSize() > targetColumnList.size())
            throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
        resultSet.bindUntypedNullsToResultColumns(targetColumnList);
        resultSet.setTableConstructorTypes(targetColumnList);
    } else {
        if (resultSet.getResultColumns().visibleSize() > resultColumnList.size())
            throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
        resultSet.bindUntypedNullsToResultColumns(resultColumnList);
        resultSet.setTableConstructorTypes(resultColumnList);
    }
    /* Bind the columns of the result set to their expressions */
    resultSet.bindResultColumns(fromList);
    int resCols = resultSet.getResultColumns().visibleSize();
    DataDictionary dd = getDataDictionary();
    if (targetColumnList != null) {
        if (targetColumnList.size() != resCols)
            throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
    } else {
        if (targetTableDescriptor != null && targetTableDescriptor.getNumberOfColumns() != resCols)
            throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
    }
    /* See if the ResultSet's RCL needs to be ordered to match the target
		 * list, or "enhanced" to accommodate defaults.  It can only need to
		 * be ordered if there is a target column list.  It needs to be
		 * enhanced if there are fewer source columns than there are columns
		 * in the table.
		 */
    boolean inOrder = true;
    int numTableColumns = resultColumnList.size();
    /* colMap[] will be the size of the target list, which could be larger
		 * than the current size of the source list.  In that case, the source
		 * list will be "enhanced" to include defaults.
		 */
    int[] colMap = new int[numTableColumns];
    // set the fields to an unused value
    for (int i = 0; i < colMap.length; i++) {
        colMap[i] = -1;
    }
    /* Create the source/target list mapping */
    if (targetColumnList != null) {
        /*
			** There is a target column list, so the result columns might
			** need to be ordered.  Step through the target column list
			** and remember the position in the target table of each column.
			** Remember if any of the columns are out of order.
			*/
        int targetSize = targetColumnList.size();
        for (int index = 0; index < targetSize; index++) {
            int position = targetColumnList.elementAt(index).getColumnDescriptor().getPosition();
            if (index != position - 1) {
                inOrder = false;
            }
            // position is 1-base; colMap indexes and entries are 0-based.
            colMap[position - 1] = index;
        }
    } else {
        /*
			** There is no target column list, so the result columns in the
			** source are presumed to be in the same order as the target
			** table.
			*/
        for (int position = 0; position < resultSet.getResultColumns().visibleSize(); position++) {
            colMap[position] = position;
        }
    }
    // Bind the ORDER BY columns
    if (orderByList != null) {
        orderByList.pullUpOrderByColumns(resultSet);
        // The select list may have new columns now, make sure to bind
        // those.
        super.bindExpressions();
        orderByList.bindOrderByColumns(resultSet);
    }
    bindOffsetFetch(offset, fetchFirst);
    resultSet = enhanceAndCheckForAutoincrement(resultSet, inOrder, colMap, defaultsWereReplaced);
    resultColumnList.checkStorableExpressions(resultSet.getResultColumns());
    /* Insert a NormalizeResultSetNode above the source if the source
		 * and target column types and lengths do not match.
 		 */
    if (!resultColumnList.columnTypesAndLengthsMatch(resultSet.getResultColumns())) {
        resultSet = new NormalizeResultSetNode(resultSet, resultColumnList, null, false, getContextManager());
    }
    if (targetTableDescriptor != null) {
        ResultColumnList sourceRCL = resultSet.getResultColumns();
        sourceRCL.copyResultColumnNames(resultColumnList);
        /* bind all generation clauses for generated columns */
        parseAndBindGenerationClauses(dataDictionary, targetTableDescriptor, sourceRCL, resultColumnList, false, null);
        /* Get and bind all constraints on the table */
        boolean[] hasDCC = new boolean[] { false /* a priori*/
        };
        checkConstraints = bindConstraints(dataDictionary, getOptimizerFactory(), targetTableDescriptor, null, sourceRCL, (int[]) null, (FormatableBitSet) null, // we always include triggers in core language
        true, hasDCC);
        hasDeferrableCheckConstraints = hasDCC[0];
        /* 
		 	** Deferred if:
			**	If the target table is also a source table
			**	Self-referencing foreign key constraint 
			**	trigger
			*/
        if (resultSet.referencesTarget(targetTableDescriptor.getName(), true) || requiresDeferredProcessing()) {
            deferred = true;
            /* Disallow bulk insert replace when target table
				 * is also a source table.
				 */
            if (bulkInsertReplace && resultSet.referencesTarget(targetTableDescriptor.getName(), true)) {
                throw StandardException.newException(SQLState.LANG_INVALID_BULK_INSERT_REPLACE, targetTableDescriptor.getQualifiedName());
            }
        }
        /* Get the list of indexes on the table being inserted into */
        getAffectedIndexes(targetTableDescriptor);
        TransactionController tc = getLanguageConnectionContext().getTransactionCompile();
        autoincRowLocation = dd.computeAutoincRowLocations(tc, targetTableDescriptor);
    } else {
        deferred = VTIDeferModPolicy.deferIt(DeferModification.INSERT_STATEMENT, targetVTI, null, resultSet);
    }
    identitySequenceUUIDString = getUUIDofSequenceGenerator();
    getCompilerContext().removePrivilegeFilter(ignorePermissions);
    getCompilerContext().popCurrentPrivType();
}
Also used : IgnoreFilter(org.apache.derby.iapi.sql.compile.IgnoreFilter) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet) TransactionController(org.apache.derby.iapi.store.access.TransactionController)

Example 2 with IgnoreFilter

use of org.apache.derby.iapi.sql.compile.IgnoreFilter in project derby by apache.

the class MergeNode method optimizeStatement.

// /////////////////////////////////////////////////////////////////////////////////
// 
// optimize() BEHAVIOR
// 
// /////////////////////////////////////////////////////////////////////////////////
@Override
public void optimizeStatement() throws StandardException {
    // 
    // Don't add any privileges during optimization.
    // 
    IgnoreFilter ignorePermissions = new IgnoreFilter();
    getCompilerContext().addPrivilegeFilter(ignorePermissions);
    /* First optimize the left join */
    _leftJoinCursor.optimizeStatement();
    // now optimize the INSERT/UPDATE/DELETE actions
    for (MatchingClauseNode mcn : _matchingClauses) {
        mcn.optimize();
    }
    // ready to add permissions again
    getCompilerContext().removePrivilegeFilter(ignorePermissions);
}
Also used : IgnoreFilter(org.apache.derby.iapi.sql.compile.IgnoreFilter)

Example 3 with IgnoreFilter

use of org.apache.derby.iapi.sql.compile.IgnoreFilter in project derby by apache.

the class DeleteNode method bindStatement.

/**
 * Bind this DeleteNode.  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>
 * If any indexes need to be updated, we add all the columns in the
 * base table to the result column list, so that we can use the column
 * values as look-up keys for the index rows to be deleted.  Binding a
 * delete will also massage the tree so that the ResultSetNode has
 * column containing the RowLocation of the base row.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    // We just need select privilege on the where clause tables
    getCompilerContext().pushCurrentPrivType(Authorizer.SELECT_PRIV);
    try {
        FromList fromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
        ResultColumn rowLocationColumn = null;
        CurrentRowLocationNode rowLocationNode;
        TableName cursorTargetTableName = null;
        CurrentOfNode currentOfNode = null;
        // 
        // Don't add privilege requirements for the UDT types of columns.
        // The compiler will attempt to add these when generating the full column list during
        // binding of the tables.
        // 
        IgnoreFilter ignorePermissions = new IgnoreFilter();
        getCompilerContext().addPrivilegeFilter(ignorePermissions);
        DataDictionary dataDictionary = getDataDictionary();
        // for DELETE clause of a MERGE statement, the tables have already been bound
        if (!inMatchingClause()) {
            super.bindTables(dataDictionary);
        }
        // for positioned delete, get the cursor's target table.
        if (SanityManager.DEBUG)
            SanityManager.ASSERT(resultSet != null && resultSet instanceof SelectNode, "Delete must have a select result set");
        SelectNode sel = (SelectNode) resultSet;
        targetTable = (FromTable) sel.fromList.elementAt(0);
        if (targetTable instanceof CurrentOfNode) {
            currentOfNode = (CurrentOfNode) targetTable;
            cursorTargetTableName = inMatchingClause() ? targetTableName : currentOfNode.getBaseCursorTargetTableName();
            // instead of an assert, we might say the cursor is not updatable.
            if (SanityManager.DEBUG)
                SanityManager.ASSERT(cursorTargetTableName != null);
        }
        if (targetTable instanceof FromVTI) {
            targetVTI = (FromVTI) targetTable;
            targetVTI.setTarget();
        } else {
            // we get it from the cursor supplying the position.
            if (targetTableName == null) {
                // verify we have current of
                if (SanityManager.DEBUG)
                    SanityManager.ASSERT(cursorTargetTableName != null);
                targetTableName = cursorTargetTableName;
            } else // the named table is the same as the cursor's target (base table name).
            if (cursorTargetTableName != null) {
                // be the same as a base name in the cursor.
                if (!targetTableName.equals(cursorTargetTableName)) {
                    throw StandardException.newException(SQLState.LANG_CURSOR_DELETE_MISMATCH, targetTableName, currentOfNode.getCursorName());
                }
            }
        }
        // descriptor must exist, tables already bound.
        verifyTargetTable();
        /* Generate a select list for the ResultSetNode - CurrentRowLocation(). */
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT((resultSet.getResultColumns() == null), "resultColumns is expected to be null until bind time");
        }
        if (targetTable instanceof FromVTI) {
            getResultColumnList();
            resultColumnList = targetTable.getResultColumnsForList(null, resultColumnList, null);
            /* Set the new result column list in the result set */
            resultSet.setResultColumns(resultColumnList);
        } else {
            /*
				** Start off assuming no columns from the base table
				** are needed in the rcl.
				*/
            resultColumnList = new ResultColumnList(getContextManager());
            FromBaseTable fbt = getResultColumnList(resultColumnList);
            readColsBitSet = getReadMap(dataDictionary, targetTableDescriptor);
            resultColumnList = fbt.addColsToList(resultColumnList, readColsBitSet);
            /*
				** If all bits are set, then behave as if we chose all
				** in the first place
				*/
            int i = 1;
            int size = targetTableDescriptor.getMaxColumnID();
            for (; i <= size; i++) {
                if (!readColsBitSet.get(i)) {
                    break;
                }
            }
            if (i > size) {
                readColsBitSet = null;
            }
            /* Generate the RowLocation column */
            rowLocationNode = new CurrentRowLocationNode(getContextManager());
            rowLocationColumn = new ResultColumn(COLUMNNAME, rowLocationNode, getContextManager());
            rowLocationColumn.markGenerated();
            /* Append to the ResultColumnList */
            resultColumnList.addResultColumn(rowLocationColumn);
            /* Force the added columns to take on the table's correlation name, if any */
            correlateAddedColumns(resultColumnList, targetTable);
            /* Add the new result columns to the driving result set */
            ResultColumnList originalRCL = resultSet.getResultColumns();
            if (originalRCL != null) {
                originalRCL.appendResultColumns(resultColumnList, false);
                resultColumnList = originalRCL;
            }
            resultSet.setResultColumns(resultColumnList);
        }
        // done excluding column types from privilege checking
        getCompilerContext().removePrivilegeFilter(ignorePermissions);
        /* Bind the expressions before the ResultColumns are bound */
        // only add privileges when we're inside the WHERE clause
        ScopeFilter scopeFilter = new ScopeFilter(getCompilerContext(), CompilerContext.WHERE_SCOPE, 1);
        getCompilerContext().addPrivilegeFilter(scopeFilter);
        super.bindExpressions();
        getCompilerContext().removePrivilegeFilter(scopeFilter);
        /* Bind untyped nulls directly under the result columns */
        resultSet.getResultColumns().bindUntypedNullsToResultColumns(resultColumnList);
        if (!(targetTable instanceof FromVTI)) {
            /* Bind the new ResultColumn */
            rowLocationColumn.bindResultColumnToExpression();
            bindConstraints(dataDictionary, getOptimizerFactory(), targetTableDescriptor, null, resultColumnList, (int[]) null, readColsBitSet, // we alway include triggers in core language
            true, // dummy
            new boolean[1]);
            /* If the target table is also a source table, then
			 	* the delete will have to be in deferred mode
			 	* For deletes, this means that the target table appears in a
			 	* subquery.  Also, self-referencing foreign key deletes
		 	 	* are deferred.  And triggers cause the delete to be deferred.
			 	*/
            if (resultSet.subqueryReferencesTarget(targetTableDescriptor.getName(), true) || requiresDeferredProcessing()) {
                deferred = true;
            }
        } else {
            deferred = VTIDeferModPolicy.deferIt(DeferModification.DELETE_STATEMENT, targetVTI, null, sel.getWhereClause());
        }
        /* 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()");
        }
        // the ref action  dependent tables and bind them.
        if (fkTableNames != null) {
            String currentTargetTableName = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName();
            if (!isDependentTable) {
                // graph node
                dependentTables = new HashSet<String>();
            }
            /*Check whether the current target has already been explored.
			 	*If we are seeing the same table name which we binded earlier
			 	*means we have cyclic references.
			 	*/
            if (dependentTables.add(currentTargetTableName)) {
                cascadeDelete = true;
                int noDependents = fkTableNames.length;
                dependentNodes = new StatementNode[noDependents];
                for (int i = 0; i < noDependents; i++) {
                    dependentNodes[i] = getDependentTableNode(fkSchemaNames[i], fkTableNames[i], fkRefActions[i], fkColDescriptors[i]);
                    dependentNodes[i].bindStatement();
                }
            }
        } else {
            // case where current dependent table does not have dependent tables
            if (isDependentTable) {
                String currentTargetTableName = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName();
                dependentTables.add(currentTargetTableName);
            }
        }
        // add need for DELETE privilege on the target table
        getCompilerContext().pushCurrentPrivType(getPrivType());
        getCompilerContext().addRequiredTablePriv(targetTableDescriptor);
        getCompilerContext().popCurrentPrivType();
    } finally {
        getCompilerContext().popCurrentPrivType();
    }
}
Also used : IgnoreFilter(org.apache.derby.iapi.sql.compile.IgnoreFilter) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) ScopeFilter(org.apache.derby.iapi.sql.compile.ScopeFilter)

Example 4 with IgnoreFilter

use of org.apache.derby.iapi.sql.compile.IgnoreFilter in project derby by apache.

the class DeleteNode method optimizeStatement.

@Override
public void optimizeStatement() throws StandardException {
    // Don't add any more permissions during pre-processing
    IgnoreFilter ignorePermissions = new IgnoreFilter();
    getCompilerContext().addPrivilegeFilter(ignorePermissions);
    if (cascadeDelete) {
        for (int index = 0; index < dependentNodes.length; index++) {
            dependentNodes[index].optimizeStatement();
        }
    }
    super.optimizeStatement();
    // allow more permissions to be added in case we're just one action
    // of a MERGE statement
    getCompilerContext().removePrivilegeFilter(ignorePermissions);
}
Also used : IgnoreFilter(org.apache.derby.iapi.sql.compile.IgnoreFilter)

Example 5 with IgnoreFilter

use of org.apache.derby.iapi.sql.compile.IgnoreFilter in project derby by apache.

the class MatchingClauseNode method bindDelete.

// //////////////
// 
// BIND DELETE
// 
// //////////////
/**
 * Bind a WHEN MATCHED ... THEN DELETE clause
 */
private void bindDelete(DataDictionary dd, FromList fullFromList, FromBaseTable targetTable) throws StandardException {
    // 
    // Don't add any privileges until we bind the DELETE.
    // 
    IgnoreFilter ignorePermissions = new IgnoreFilter();
    getCompilerContext().addPrivilegeFilter(ignorePermissions);
    FromBaseTable deleteTarget = new FromBaseTable(targetTable.getTableNameField(), null, null, null, getContextManager());
    FromList dummyFromList = new FromList(getContextManager());
    dummyFromList.addFromTable(deleteTarget);
    dummyFromList.bindTables(dd, new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()));
    CurrentOfNode currentOfNode = CurrentOfNode.makeForMerge(CURRENT_OF_NODE_NAME, deleteTarget, getContextManager());
    FromList fromList = new FromList(getContextManager());
    fromList.addFromTable(currentOfNode);
    SelectNode selectNode = new SelectNode(null, fromList, /* FROM list */
    null, /* WHERE clause */
    null, /* GROUP BY list */
    null, /* having clause */
    null, /* window list */
    null, /* optimizer plan override */
    getContextManager());
    _dml = new DeleteNode(targetTable.getTableNameField(), selectNode, this, getContextManager());
    // ready to add permissions
    getCompilerContext().removePrivilegeFilter(ignorePermissions);
    _dml.bindStatement();
    buildThenColumnsForDelete();
}
Also used : IgnoreFilter(org.apache.derby.iapi.sql.compile.IgnoreFilter)

Aggregations

IgnoreFilter (org.apache.derby.iapi.sql.compile.IgnoreFilter)8 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)3 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)1 ScopeFilter (org.apache.derby.iapi.sql.compile.ScopeFilter)1 TransactionController (org.apache.derby.iapi.store.access.TransactionController)1