use of org.apache.derby.iapi.sql.depend.ProviderList in project derby by apache.
the class ColumnDefinitionNode method validateDefault.
/**
* Check the validity of the default for this node.
*
* @param td The TableDescriptor.
*
* @exception StandardException Thrown on error
*/
void validateDefault(DataDictionary dd, TableDescriptor td) throws StandardException {
if (defaultNode == null)
return;
// Examin whether default value is autoincrement.
if (isAutoincrement) {
defaultInfo = createDefaultInfoOfAutoInc();
return;
}
// Judged as default value is constant value.
CompilerContext cc = getCompilerContext();
ValueNode defaultTree = defaultNode.getDefaultTree();
/* bind the default.
* Verify that it does not contain any ColumnReferences or subqueries
* and that it is type compatable with the column.
*/
final int previousReliability = cc.getReliability();
try {
/*
Defaults cannot have dependencies as they
should just be constants. Code used to exist
to handle dependencies in defaults, now this
is under sanity to ensure no dependencies exist.
*/
ProviderList apl = null;
ProviderList prevAPL = null;
if (SanityManager.DEBUG) {
apl = new ProviderList();
prevAPL = cc.getCurrentAuxiliaryProviderList();
cc.setCurrentAuxiliaryProviderList(apl);
}
// Tell the compiler context to only allow deterministic nodes
cc.setReliability(CompilerContext.DEFAULT_RESTRICTION);
defaultTree = defaultTree.bindExpression(new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()), (SubqueryList) null, (List<AggregateNode>) null);
TypeId columnTypeId = getType().getTypeId();
TypeId defaultTypeId = defaultTree.getTypeId();
// before checking for 'not storable' errors (42821).
if (!defaultTypeIsValid(columnTypeId, getType(), defaultTypeId, defaultTree, defaultNode.getDefaultText())) {
throw StandardException.newException(SQLState.LANG_DB2_INVALID_DEFAULT_VALUE, this.name);
}
// Now check 'not storable' errors.
if (!getTypeCompiler(columnTypeId).storable(defaultTypeId, getClassFactory())) {
throw StandardException.newException(SQLState.LANG_NOT_STORABLE, columnTypeId.getSQLTypeName(), defaultTypeId.getSQLTypeName());
}
// Save off the default text
// RESOLVEDEFAULT - Convert to constant if possible
defaultInfo = new DefaultInfoImpl(false, defaultNode.getDefaultText(), defaultValue);
if (SanityManager.DEBUG) {
/* Save the APL off in the constraint node */
if (apl.size() > 0) {
SanityManager.THROWASSERT("DEFAULT clause has unexpected dependencies");
}
// Restore the previous AuxiliaryProviderList
cc.setCurrentAuxiliaryProviderList(prevAPL);
}
} finally {
cc.setReliability(previousReliability);
}
}
use of org.apache.derby.iapi.sql.depend.ProviderList in project derby by apache.
the class CreateTableNode method bindStatement.
// We inherit the generate() method from DDLStatementNode.
/**
* Bind this CreateTableNode. This means doing any static error checking that can be
* done before actually creating the base table or declaring the global temporary table.
* For eg, verifying that the TableElementList does not contain any duplicate column names.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
DataDictionary dataDictionary = getDataDictionary();
int numPrimaryKeys;
int numCheckConstraints;
int numReferenceConstraints;
int numUniqueConstraints;
int numGenerationClauses;
SchemaDescriptor sd = getSchemaDescriptor(tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, true);
if (queryExpression != null) {
FromList fromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
CompilerContext cc = getCompilerContext();
ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();
ProviderList apl = new ProviderList();
try {
cc.setCurrentAuxiliaryProviderList(apl);
cc.pushCurrentPrivType(Authorizer.SELECT_PRIV);
/* Bind the tables in the queryExpression */
queryExpression = queryExpression.bindNonVTITables(dataDictionary, fromList);
queryExpression = queryExpression.bindVTITables(fromList);
/* Bind the expressions under the resultSet */
queryExpression.bindExpressions(fromList);
/* Bind the query expression */
queryExpression.bindResultColumns(fromList);
/* Reject any untyped nulls in the RCL */
/* e.g. CREATE TABLE t1 (x) AS VALUES NULL WITH NO DATA */
queryExpression.bindUntypedNullsToResultColumns(null);
} finally {
cc.popCurrentPrivType();
cc.setCurrentAuxiliaryProviderList(prevAPL);
}
/* If there is an RCL for the table definition then copy the
* names to the queryExpression's RCL after verifying that
* they both have the same size.
*/
ResultColumnList qeRCL = queryExpression.getResultColumns();
if (resultColumns != null) {
if (resultColumns.size() != qeRCL.visibleSize()) {
throw StandardException.newException(SQLState.LANG_TABLE_DEFINITION_R_C_L_MISMATCH, getFullName());
}
qeRCL.copyResultColumnNames(resultColumns);
}
int schemaCollationType = sd.getCollationType();
/* Create table element list from columns in query expression */
tableElementList = new TableElementList(getContextManager());
for (ResultColumn rc : qeRCL) {
if (rc.isGenerated()) {
continue;
}
/* Raise error if column name is system generated. */
if (rc.isNameGenerated()) {
throw StandardException.newException(SQLState.LANG_TABLE_REQUIRES_COLUMN_NAMES);
}
DataTypeDescriptor dtd = rc.getExpression().getTypeServices();
if ((dtd != null) && !dtd.isUserCreatableType()) {
throw StandardException.newException(SQLState.LANG_INVALID_COLUMN_TYPE_CREATE_TABLE, dtd.getFullSQLTypeName(), rc.getName());
}
// a territory based database.
if (dtd.getTypeId().isStringTypeId() && dtd.getCollationType() != schemaCollationType) {
throw StandardException.newException(SQLState.LANG_CAN_NOT_CREATE_TABLE, dtd.getCollationName(), DataTypeDescriptor.getCollationName(schemaCollationType));
}
ColumnDefinitionNode column = new ColumnDefinitionNode(rc.getName(), null, rc.getType(), null, getContextManager());
tableElementList.addTableElement(column);
}
} else {
// Set the collation type and collation derivation of all the
// character type columns. Their collation type will be same as the
// collation of the schema they belong to. Their collation
// derivation will be "implicit".
// Earlier we did this in makeConstantAction but that is little too
// late (DERBY-2955)
// eg
// CREATE TABLE STAFF9 (EMPNAME CHAR(20),
// CONSTRAINT STAFF9_EMPNAME CHECK (EMPNAME NOT LIKE 'T%'))
// For the query above, when run in a territory based db, we need
// to have the correct collation set in bind phase of create table
// so that when LIKE is handled in LikeEscapeOperatorNode, we have
// the correct collation set for EMPNAME otherwise it will throw an
// exception for 'T%' having collation of territory based and
// EMPNAME having the default collation of UCS_BASIC
tableElementList.setCollationTypesOnCharacterStringColumns(getSchemaDescriptor(tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, true));
}
tableElementList.validate(this, dataDictionary, (TableDescriptor) null);
/* Only 1012 columns allowed per table */
if (tableElementList.countNumberOfColumns() > Limits.DB2_MAX_COLUMNS_IN_TABLE) {
throw StandardException.newException(SQLState.LANG_TOO_MANY_COLUMNS_IN_TABLE_OR_VIEW, String.valueOf(tableElementList.countNumberOfColumns()), getRelativeName(), String.valueOf(Limits.DB2_MAX_COLUMNS_IN_TABLE));
}
numPrimaryKeys = tableElementList.countConstraints(DataDictionary.PRIMARYKEY_CONSTRAINT);
/* Only 1 primary key allowed per table */
if (numPrimaryKeys > 1) {
throw StandardException.newException(SQLState.LANG_TOO_MANY_PRIMARY_KEY_CONSTRAINTS, getRelativeName());
}
/* Check the validity of all check constraints */
numCheckConstraints = tableElementList.countConstraints(DataDictionary.CHECK_CONSTRAINT);
numReferenceConstraints = tableElementList.countConstraints(DataDictionary.FOREIGNKEY_CONSTRAINT);
numUniqueConstraints = tableElementList.countConstraints(DataDictionary.UNIQUE_CONSTRAINT);
numGenerationClauses = tableElementList.countGenerationClauses();
// temp tables can't have primary key or check or foreign key or unique constraints defined on them
if ((tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) && (numPrimaryKeys > 0 || numCheckConstraints > 0 || numReferenceConstraints > 0 || numUniqueConstraints > 0))
throw StandardException.newException(SQLState.LANG_NOT_ALLOWED_FOR_DECLARED_GLOBAL_TEMP_TABLE);
// more than 32767 indexes on it and that is why this check.
if ((numPrimaryKeys + numReferenceConstraints + numUniqueConstraints) > Limits.DB2_MAX_INDEXES_ON_TABLE) {
throw StandardException.newException(SQLState.LANG_TOO_MANY_INDEXES_ON_TABLE, String.valueOf(numPrimaryKeys + numReferenceConstraints + numUniqueConstraints), getRelativeName(), String.valueOf(Limits.DB2_MAX_INDEXES_ON_TABLE));
}
if ((numCheckConstraints > 0) || (numGenerationClauses > 0) || (numReferenceConstraints > 0)) {
/* In order to check the validity of the check constraints and
* generation clauses
* we must goober up a FromList containing a single table,
* the table being created, with an RCL containing the
* new columns and their types. This will allow us to
* bind the constraint definition trees against that
* FromList. When doing this, we verify that there are
* no nodes which can return non-deterministic results.
*/
FromList fromList = makeFromList(null, tableElementList, true);
FormatableBitSet generatedColumns = new FormatableBitSet();
/* Now that we've finally goobered stuff up, bind and validate
* the check constraints and generation clauses.
*/
if (numGenerationClauses > 0) {
tableElementList.bindAndValidateGenerationClauses(sd, fromList, generatedColumns, null);
}
if (numCheckConstraints > 0) {
tableElementList.bindAndValidateCheckConstraints(fromList);
}
if (numReferenceConstraints > 0) {
tableElementList.validateForeignKeysOnGenerationClauses(fromList, generatedColumns);
}
}
if (numPrimaryKeys > 0) {
tableElementList.validatePrimaryKeyNullability();
}
}
use of org.apache.derby.iapi.sql.depend.ProviderList 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.depend.ProviderList 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.ProviderList 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;
}
Aggregations