use of org.apache.derby.iapi.sql.depend.ProviderInfo in project derby by apache.
the class BasicDependencyManager method getPersistentProviderInfos.
/**
* @see DependencyManager#getPersistentProviderInfos
*
* @exception StandardException Thrown on error
*/
public ProviderInfo[] getPersistentProviderInfos(Dependent dependent) throws StandardException {
List<Provider> provs = getProviders(dependent);
if (provs.isEmpty()) {
return EMPTY_PROVIDER_INFO;
}
List<ProviderInfo> pih = new ArrayList<ProviderInfo>();
for (Provider p : provs) {
if (p.isPersistent()) {
pih.add(new BasicProviderInfo(p.getObjectID(), p.getDependableFinder(), p.getObjectName()));
}
}
return (ProviderInfo[]) pih.toArray(EMPTY_PROVIDER_INFO);
}
use of org.apache.derby.iapi.sql.depend.ProviderInfo in project derby by apache.
the class TableElementList method genConstraintActions.
/**
* Fill in the ConstraintConstantAction[] for this create/alter table.
*
* @param forCreateTable ConstraintConstantAction is for a create table.
* @param conActions The ConstraintConstantAction[] to be filled in.
* @param tableName The name of the Table being created.
* @param tableSd The schema for that table.
* @param dd The DataDictionary
*
* @exception StandardException Thrown on failure
*/
void genConstraintActions(boolean forCreateTable, ConstraintConstantAction[] conActions, String tableName, SchemaDescriptor tableSd, DataDictionary dd) throws StandardException {
int conActionIndex = 0;
for (TableElementNode ten : this) {
String[] columnNames = null;
IndexConstantAction indexAction = null;
if (!ten.hasConstraint() || ten instanceof ColumnDefinitionNode) {
continue;
}
ConstraintDefinitionNode constraintDN = (ConstraintDefinitionNode) ten;
if (constraintDN.getColumnList() != null) {
columnNames = new String[constraintDN.getColumnList().size()];
constraintDN.getColumnList().exportNames(columnNames);
}
int constraintType = constraintDN.getConstraintType();
boolean[] cChars = constraintDN.getCharacteristics();
String constraintText = constraintDN.getConstraintText();
/*
** If the constraint is not named (e.g.
** create table x (x int primary key)), then
** the constraintSd is the same as the table.
*/
String constraintName = constraintDN.getConstraintMoniker();
/* At execution time, we will generate a unique name for the backing
* index (for CREATE CONSTRAINT) and we will look up the conglomerate
* name (for DROP CONSTRAINT).
*/
if (constraintDN.requiresBackingIndex()) {
if (constraintDN.constraintType == DataDictionary.UNIQUE_CONSTRAINT && (dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null))) {
boolean contains_nullable_columns = areColumnsNullable(constraintDN, td);
// if all the columns are non nullable, continue to use
// a unique backing index.
boolean unique = !contains_nullable_columns;
// Only use a "unique with duplicate nulls" backing index
// for constraints with nullable columns.
boolean uniqueWithDuplicateNulls = contains_nullable_columns;
indexAction = genIndexAction(forCreateTable, unique, uniqueWithDuplicateNulls, // deferrable?
cChars[0], // initiallyDeferred?
cChars[1], null, constraintDN, columnNames, true, tableSd, tableName, constraintType, dd);
} else {
// PRIMARY KEY, FOREIGN KEY
// For foreign key constraint we do no mark the
// index as deferrable; since checking isn't done on
// duplicate keys there.
indexAction = genIndexAction(forCreateTable, constraintDN.requiresUniqueIndex(), false, cChars[0], cChars[1], null, constraintDN, columnNames, true, tableSd, tableName, constraintType, dd);
}
}
if (constraintType == DataDictionary.DROP_CONSTRAINT) {
if (SanityManager.DEBUG) {
// Can't drop constraints on a create table.
SanityManager.ASSERT(!forCreateTable);
}
conActions[conActionIndex] = getGenericConstantActionFactory().getDropConstraintConstantAction(constraintName, // / FiX
constraintDN.getDropSchemaName(), tableName, td.getUUID(), tableSd.getSchemaName(), indexAction, constraintDN.getDropBehavior(), constraintDN.getVerifyType());
} else if (constraintType == DataDictionary.MODIFY_CONSTRAINT) {
conActions[conActionIndex] = getGenericConstantActionFactory().getAlterConstraintConstantAction(constraintName, constraintDN.getDropSchemaName(), cChars, tableName, td.getUUID(), tableSd.getSchemaName(), indexAction);
} else {
ProviderList apl = constraintDN.getAuxiliaryProviderList();
ConstraintInfo refInfo = null;
ProviderInfo[] providerInfos;
if (constraintDN instanceof FKConstraintDefinitionNode) {
refInfo = ((FKConstraintDefinitionNode) constraintDN).getReferencedConstraintInfo();
}
/* Create the ProviderInfos, if the constraint is dependent on any Providers */
if (apl != null && apl.size() > 0) {
/* Get all the dependencies for the current statement and transfer
* them to this view.
*/
DependencyManager dm = dd.getDependencyManager();
providerInfos = dm.getPersistentProviderInfos(apl);
} else {
providerInfos = new ProviderInfo[0];
// System.out.println("TABLE ELEMENT LIST EMPTY");
}
conActions[conActionIndex++] = getGenericConstantActionFactory().getCreateConstraintConstantAction(constraintName, constraintType, cChars, forCreateTable, tableName, ((td != null) ? td.getUUID() : (UUID) null), tableSd.getSchemaName(), columnNames, indexAction, constraintText, refInfo, providerInfos);
}
}
}
use of org.apache.derby.iapi.sql.depend.ProviderInfo in project derby by apache.
the class TableElementList method genColumnInfos.
/**
* Fill in the ColumnInfo[] for this table element list.
*
* @param colInfos The ColumnInfo[] to be filled in.
*
* @return int The number of constraints in the create table.
*/
int genColumnInfos(ColumnInfo[] colInfos) throws StandardException {
int numConstraints = 0;
int size = size();
for (int index = 0; index < size; index++) {
if (elementAt(index).getElementType() == TableElementNode.AT_DROP_COLUMN) {
String columnName = elementAt(index).getName();
colInfos[index] = new ColumnInfo(columnName, td.getColumnDescriptor(columnName).getType(), null, null, null, null, null, ColumnInfo.DROP, 0, 0, false, 0);
break;
}
if (!(elementAt(index) instanceof ColumnDefinitionNode)) {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(elementAt(index) instanceof ConstraintDefinitionNode, "elementAt(index) expected to be instanceof " + "ConstraintDefinitionNode");
}
/* Remember how many constraints we've seen */
numConstraints++;
continue;
}
ColumnDefinitionNode coldef = (ColumnDefinitionNode) elementAt(index);
//
// Generated columns may depend on functions mentioned in their
// generation clauses.
//
ProviderList apl = null;
ProviderInfo[] providerInfos = null;
if (coldef.hasGenerationClause()) {
apl = coldef.getGenerationClauseNode().getAuxiliaryProviderList();
}
if (apl != null && apl.size() > 0) {
DependencyManager dm = getDataDictionary().getDependencyManager();
providerInfos = dm.getPersistentProviderInfos(apl);
}
colInfos[index - numConstraints] = new ColumnInfo(coldef.getColumnName(), coldef.getType(), coldef.getDefaultValue(), coldef.getDefaultInfo(), providerInfos, (UUID) null, coldef.getOldDefaultUUID(), coldef.getAction(), (coldef.isAutoincrementColumn() ? coldef.getAutoincrementStart() : 0), (coldef.isAutoincrementColumn() ? coldef.getAutoincrementIncrement() : 0), (coldef.isAutoincrementColumn() ? coldef.getAutoincrementCycle() : false), (coldef.isAutoincrementColumn() ? coldef.getAutoinc_create_or_modify_Start_Increment() : -1));
/* Remember how many constraints that we've seen */
if (coldef.hasConstraint()) {
numConstraints++;
}
}
return numConstraints;
}
use of org.apache.derby.iapi.sql.depend.ProviderInfo in project derby by apache.
the class CreateTriggerConstantAction method executeConstantAction.
/**
* This is the guts of the Execution-time logic for CREATE TRIGGER.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
SPSDescriptor whenspsd = null;
SPSDescriptor actionspsd;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
/*
** Indicate that we are about to modify the data dictionary.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
SchemaDescriptor triggerSd = getSchemaDescriptorForCreate(dd, activation, triggerSchemaName);
if (spsCompSchemaId == null) {
SchemaDescriptor def = lcc.getDefaultSchema();
if (def.getUUID() == null) {
// Descriptor for default schema is stale,
// look it up in the dictionary
def = dd.getSchemaDescriptor(def.getDescriptorName(), tc, false);
}
/*
** It is possible for spsCompSchemaId to be null. For instance,
** the current schema may not have been physically created yet but
** it exists "virtually". In this case, its UUID will have the
** value of null meaning that it is not persistent. e.g.:
**
** CONNECT 'db;create=true' user 'ernie';
** CREATE TABLE bert.t1 (i INT);
** CREATE TRIGGER bert.tr1 AFTER INSERT ON bert.t1
** FOR EACH STATEMENT MODE DB2SQL
** SELECT * FROM SYS.SYSTABLES;
**
** Note that in the above case, the trigger action statement have a
** null compilation schema. A compilation schema with null value
** indicates that the trigger action statement text does not have
** any dependencies with the CURRENT SCHEMA. This means:
**
** o It is safe to compile this statement in any schema since
** there is no dependency with the CURRENT SCHEMA. i.e.: All
** relevent identifiers are qualified with a specific schema.
**
** o The statement cache mechanism can utilize this piece of
** information to enable better statement plan sharing across
** connections in different schemas; thus, avoiding unnecessary
** statement compilation.
*/
if (def != null)
spsCompSchemaId = def.getUUID();
}
String tabName;
if (triggerTable != null) {
triggerTableId = triggerTable.getUUID();
tabName = triggerTable.getName();
} else
tabName = "with UUID " + triggerTableId;
/* We need to get table descriptor again. We simply can't trust the
* one we got at compile time, the lock on system table was released
* when compile was done, and the table might well have been dropped.
*/
triggerTable = dd.getTableDescriptor(triggerTableId);
if (triggerTable == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tabName);
}
/* Lock the table for DDL. Otherwise during our execution, the table
* might be changed, even dropped. Beetle 4269
*/
lockTableForDDL(tc, triggerTable.getHeapConglomerateId(), true);
/* get triggerTable again for correctness, in case it's changed before
* the lock is aquired
*/
triggerTable = dd.getTableDescriptor(triggerTableId);
if (triggerTable == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tabName);
}
/*
** Send an invalidate on the table from which
** the triggering event emanates. This it
** to make sure that DML statements on this table
** will be recompiled. Do this before we create
** our trigger spses lest we invalidate them just
** after creating them.
*/
dm.invalidateFor(triggerTable, DependencyManager.CREATE_TRIGGER, lcc);
/*
** Lets get our trigger id up front, we'll use it when
** we create our spses.
*/
UUID tmpTriggerId = dd.getUUIDFactory().createUUID();
actionSPSId = (actionSPSId == null) ? dd.getUUIDFactory().createUUID() : actionSPSId;
if (whenSPSId == null && whenText != null) {
whenSPSId = dd.getUUIDFactory().createUUID();
}
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
/*
** Create the trigger descriptor first so the trigger action
** compilation can pick up the relevant trigger especially in
** the case of self triggering.
*/
TriggerDescriptor triggerd = ddg.newTriggerDescriptor(triggerSd, tmpTriggerId, triggerName, eventMask, isBefore, isRow, isEnabled, triggerTable, whenSPSId, actionSPSId, makeCreationTimestamp(dd), referencedCols, referencedColsInTriggerAction, originalActionText, referencingOld, referencingNew, oldReferencingName, newReferencingName, originalWhenText);
dd.addDescriptor(triggerd, triggerSd, DataDictionary.SYSTRIGGERS_CATALOG_NUM, false, tc);
/*
** If we have a WHEN action we create it now.
*/
if (whenText != null) {
// The WHEN clause is just a search condition and not a full
// SQL statement. Turn in into a VALUES statement.
String whenValuesStmt = "VALUES " + whenText;
whenspsd = createSPS(lcc, ddg, dd, tc, tmpTriggerId, triggerSd, whenSPSId, spsCompSchemaId, whenValuesStmt, true, triggerTable);
}
/*
** Create the trigger action
*/
actionspsd = createSPS(lcc, ddg, dd, tc, tmpTriggerId, triggerSd, actionSPSId, spsCompSchemaId, actionText, false, triggerTable);
/*
** Make underlying spses dependent on the trigger.
*/
if (whenspsd != null) {
dm.addDependency(triggerd, whenspsd, lcc.getContextManager());
}
dm.addDependency(triggerd, actionspsd, lcc.getContextManager());
dm.addDependency(triggerd, triggerTable, lcc.getContextManager());
// from the triggered statement or the WHEN clause.
for (ProviderInfo info : providerInfo) {
Provider provider = (Provider) info.getDependableFinder().getDependable(dd, info.getObjectId());
dm.addDependency(triggerd, provider, lcc.getContextManager());
}
// store trigger's dependency on various privileges in the dependeny system
storeViewTriggerDependenciesOnPrivileges(activation, triggerd);
}
use of org.apache.derby.iapi.sql.depend.ProviderInfo in project derby by apache.
the class DDLConstantAction method addColumnDependencies.
/**
* Add dependencies of a column on providers. These can arise if a generated column depends
* on a user created function.
*/
protected void addColumnDependencies(LanguageConnectionContext lcc, DataDictionary dd, TableDescriptor td, ColumnInfo ci) throws StandardException {
ProviderInfo[] providers = ci.providers;
if (providers != null) {
DependencyManager dm = dd.getDependencyManager();
ContextManager cm = lcc.getContextManager();
int providerCount = providers.length;
ColumnDescriptor cd = td.getColumnDescriptor(ci.name);
DefaultDescriptor defDesc = cd.getDefaultDescriptor(dd);
for (int px = 0; px < providerCount; px++) {
ProviderInfo pi = providers[px];
DependableFinder finder = pi.getDependableFinder();
UUID providerID = pi.getObjectId();
Provider provider = (Provider) finder.getDependable(dd, providerID);
dm.addDependency(defDesc, provider, cm);
}
// end loop through providers
}
}
Aggregations