baseTableRestrictionList = (PredicateList) getNodeFactory().getNode(
C_NodeTypes.PREDICATE_LIST,
getContextManager());
CompilerContext compilerContext = getCompilerContext();
/* Generate the ResultColumnList */
resultColumns = genResultColList();
templateColumns = resultColumns;
/* Resolve the view, if this is a view */
if (tableDescriptor.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(tableDescriptor);
/*
** 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);
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(vd != null,
"vd not expected to be null for " + tableName);
}
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())
{
resultColumns.setCountMismatchAllowed(true);
}
//Views execute with definer's privileges and if any one of
//those privileges' are revoked from the definer, the view gets
//dropped. So, a view can exist in Derby only if it's owner has
//all the privileges needed to create one. In order to do a
//select from a view, a user only needs select privilege on the
//view and doesn't need any privilege for objects accessed by
//the view. Hence, when collecting privilege requirement for a
//sql accessing a view, we only need to look for select privilege
//on the actual view and that is what the following code is
//checking.
for (int i = 0; i < resultColumns.size(); i++) {
ResultColumn rc = (ResultColumn) resultColumns.elementAt(i);
if (rc.isPrivilegeCollectionRequired())
compilerContext.addRequiredColumnPriv( rc.getTableColumnDescriptor());
}
fsq = (FromSubquery) getNodeFactory().getNode(
C_NodeTypes.FROM_SUBQUERY,
rsn,
cvn.getOrderByList(),
cvn.getOffset(),
cvn.getFetchFirst(),
(correlationName != null) ?
correlationName : getOrigTableName().getTableName(),
resultColumns,
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.
fsq.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(tableDescriptor);
/* Get the base conglomerate descriptor */
baseConglomerateDescriptor =
tableDescriptor.getConglomerateDescriptor(
tableDescriptor.getHeapConglomerateId()
);
/* Build the 0-based array of base column names. */
columnNames = resultColumns.getColumnNames();
/* Do error checking on derived column list and update "exposed"
* column names if valid.
*/
if (derivedRCL != null)
{
resultColumns.propagateDCLInfo(derivedRCL,
origTableName.getFullTableName());
}
/* Assign the tableNumber */
if (tableNumber == -1) // allow re-bind, in which case use old number
tableNumber = compilerContext.getNextTableNumber();
}
return this;
}