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