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();
}
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);
}
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();
}
}
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);
}
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();
}
Aggregations