use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class FromBaseTable method bindTableDescriptor.
/**
* Bind the table descriptor for this table.
*
* If the tableName is a synonym, it will be resolved here.
* The original table name is retained in origTableName.
*
* @exception StandardException Thrown on error
*/
private TableDescriptor bindTableDescriptor() throws StandardException {
String schemaName = tableName.getSchemaName();
SchemaDescriptor sd = getSchemaDescriptor(schemaName);
tableDescriptor = getTableDescriptor(tableName.getTableName(), sd);
if (tableDescriptor == null) {
// Check if the reference is for a synonym.
TableName synonymTab = resolveTableToSynonym(tableName);
if (synonymTab == null)
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
tableName = synonymTab;
sd = getSchemaDescriptor(tableName.getSchemaName());
tableDescriptor = getTableDescriptor(synonymTab.getTableName(), sd);
if (tableDescriptor == null)
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, tableName);
}
return tableDescriptor;
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class FromBaseTable method bindNonVTITables.
/**
* Bind the table in this FromBaseTable.
* This is where view resolution occurs
*
* @param dataDictionary The DataDictionary to use for binding
* @param fromListParam FromList to use/append to.
*
* @return ResultSetNode The FromTable for the table or resolved view.
*
* @exception StandardException Thrown on error
*/
@Override
ResultSetNode bindNonVTITables(DataDictionary dataDictionary, FromList fromListParam) throws StandardException {
tableName.bind();
TableDescriptor tabDescr = bindTableDescriptor();
if (tabDescr.getTableType() == TableDescriptor.VTI_TYPE) {
ResultSetNode vtiNode = mapTableAsVTI(tabDescr, getCorrelationName(), getResultColumns(), getProperties(), getContextManager());
return vtiNode.bindNonVTITables(dataDictionary, fromListParam);
}
ResultColumnList derivedRCL = getResultColumns();
// make sure there's a restriction list
restrictionList = new PredicateList(getContextManager());
baseTableRestrictionList = new PredicateList(getContextManager());
CompilerContext compilerContext = getCompilerContext();
/* Generate the ResultColumnList */
setResultColumns(genResultColList());
templateColumns = getResultColumns();
/* Resolve the view, if this is a view */
if (tabDescr.getTableType() == TableDescriptor.VIEW_TYPE) {
FromSubquery fsq;
ResultSetNode rsn;
ViewDescriptor vd;
CreateViewNode cvn;
SchemaDescriptor compSchema;
/* Get the associated ViewDescriptor so that we can get
* the view definition text.
*/
vd = dataDictionary.getViewDescriptor(tabDescr);
/*
** Set the default compilation schema to be whatever
** this schema this view was originally compiled against.
** That way we pick up the same tables no matter what
** schema we are running against.
*/
compSchema = dataDictionary.getSchemaDescriptor(vd.getCompSchemaId(), null);
compilerContext.pushCompilationSchema(compSchema);
try {
/* This represents a view - query is dependent on the ViewDescriptor */
compilerContext.createDependency(vd);
cvn = (CreateViewNode) parseStatement(vd.getViewText(), false);
rsn = cvn.getParsedQueryExpression();
/* If the view contains a '*' then we mark the views derived column list
* so that the view will still work, and return the expected results,
* if any of the tables referenced in the view have columns added to
* them via ALTER TABLE. The expected results means that the view
* will always return the same # of columns.
*/
if (rsn.getResultColumns().containsAllResultColumn()) {
getResultColumns().setCountMismatchAllowed(true);
}
// checking.
for (ResultColumn rc : getResultColumns()) {
if (isPrivilegeCollectionRequired()) {
compilerContext.addRequiredColumnPriv(rc.getTableColumnDescriptor());
}
}
fsq = new FromSubquery(rsn, cvn.getOrderByList(), cvn.getOffset(), cvn.getFetchFirst(), cvn.hasJDBClimitClause(), (correlationName != null) ? correlationName : getOrigTableName().getTableName(), getResultColumns(), tableProperties, getContextManager());
// Transfer the nesting level to the new FromSubquery
fsq.setLevel(level);
// We are getting ready to bind the query underneath the view. Since
// that query is going to run with definer's privileges, we do not
// need to collect any privilege requirement for that query.
// Following call is marking the query to run with definer
// privileges. This marking will make sure that we do not collect
// any privilege requirement for it.
CollectNodesVisitor<QueryTreeNode> cnv = new CollectNodesVisitor<QueryTreeNode>(QueryTreeNode.class);
fsq.accept(cnv);
for (QueryTreeNode node : cnv.getList()) {
node.disablePrivilegeCollection();
}
fsq.setOrigTableName(this.getOrigTableName());
// since we reset the compilation schema when we return, we
// need to save it for use when we bind expressions:
fsq.setOrigCompilationSchema(compSchema);
ResultSetNode fsqBound = fsq.bindNonVTITables(dataDictionary, fromListParam);
/* Do error checking on derived column list and update "exposed"
* column names if valid.
*/
if (derivedRCL != null) {
fsqBound.getResultColumns().propagateDCLInfo(derivedRCL, origTableName.getFullTableName());
}
return fsqBound;
} finally {
compilerContext.popCompilationSchema();
}
} else {
/* This represents a table - query is dependent on the TableDescriptor */
compilerContext.createDependency(tabDescr);
/* Get the base conglomerate descriptor */
baseConglomerateDescriptor = tabDescr.getConglomerateDescriptor(tabDescr.getHeapConglomerateId());
// probably doesn't exist anymore.
if (baseConglomerateDescriptor == null) {
throw StandardException.newException(SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST, Long.valueOf(tabDescr.getHeapConglomerateId()));
}
/* Build the 0-based array of base column names. */
columnNames = getResultColumns().getColumnNames();
/* Do error checking on derived column list and update "exposed"
* column names if valid.
*/
if (derivedRCL != null) {
getResultColumns().propagateDCLInfo(derivedRCL, origTableName.getFullTableName());
}
/* Assign the tableNumber */
if (// allow re-bind, in which case use old number
tableNumber == -1)
tableNumber = compilerContext.getNextTableNumber();
}
//
// Only the DBO can select from SYS.SYSUSERS.
//
authorizeSYSUSERS = dataDictionary.usesSqlAuthorization() && tabDescr.getUUID().toString().equals(SYSUSERSRowFactory.SYSUSERS_UUID);
if (authorizeSYSUSERS) {
String databaseOwner = dataDictionary.getAuthorizationDatabaseOwner();
String currentUser = getLanguageConnectionContext().getStatementContext().getSQLSessionContext().getCurrentUser();
if (!databaseOwner.equals(currentUser)) {
throw StandardException.newException(SQLState.DBO_ONLY);
}
}
return this;
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class CompilerContextImpl method setCompilationSchema.
/**
* Set the compilation schema descriptor for this compilation context.
*
* @param newDefault the compilation schema
*
* @return the previous compilation schema descirptor
*/
public SchemaDescriptor setCompilationSchema(SchemaDescriptor newDefault) {
SchemaDescriptor tmpSchema = compilationSchema;
compilationSchema = newDefault;
return tmpSchema;
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor in project derby by apache.
the class CreateTableNode method makeConstantAction.
/**
* Create the Constant information that will drive the guts of Execution.
*
* @exception StandardException Thrown on failure
*/
@Override
public ConstantAction makeConstantAction() throws StandardException {
TableElementList coldefs = tableElementList;
// for each column, stuff system.column
ColumnInfo[] colInfos = new ColumnInfo[coldefs.countNumberOfColumns()];
int numConstraints = coldefs.genColumnInfos(colInfos);
/* If we've seen a constraint, then build a constraint list */
CreateConstraintConstantAction[] conActions = null;
SchemaDescriptor sd = getSchemaDescriptor(tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE, true);
if (numConstraints > 0) {
conActions = new CreateConstraintConstantAction[numConstraints];
coldefs.genConstraintActions(true, conActions, getRelativeName(), sd, getDataDictionary());
}
// if the any of columns are "long" and user has not specified a
// page size, set the pagesize to 32k.
// Also in case where the approximate sum of the column sizes is
// greater than the bump threshold , bump the pagesize to 32k
boolean table_has_long_column = false;
int approxLength = 0;
for (int i = 0; i < colInfos.length; i++) {
DataTypeDescriptor dts = colInfos[i].getDataType();
if (dts.getTypeId().isLongConcatableTypeId()) {
table_has_long_column = true;
break;
}
approxLength += dts.getTypeId().getApproximateLengthInBytes(dts);
}
if (table_has_long_column || (approxLength > Property.TBL_PAGE_SIZE_BUMP_THRESHOLD)) {
if (((properties == null) || (properties.get(Property.PAGE_SIZE_PARAMETER) == null)) && (PropertyUtil.getServiceProperty(getLanguageConnectionContext().getTransactionCompile(), Property.PAGE_SIZE_PARAMETER) == null)) {
if (properties == null)
properties = new Properties();
properties.put(Property.PAGE_SIZE_PARAMETER, Property.PAGE_SIZE_DEFAULT_LONG);
}
}
return (getGenericConstantActionFactory().getCreateTableConstantAction(sd.getSchemaName(), getRelativeName(), tableType, colInfos, conActions, properties, lockGranularity, onCommitDeleteRows, onRollbackDeleteRows));
}
use of org.apache.derby.iapi.sql.dictionary.SchemaDescriptor 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();
}
}
Aggregations