package org.hsqldb;
import org.hsqldb.HsqlNameManager.HsqlName;
import org.hsqldb.ParserDQL.CompileContext;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.OrderedHashSet;
public class View extends TableDerived {
private String statement;
private HsqlName[] columnNames;
private OrderedHashSet schemaObjectNames;
private int checkOption;
private Table baseTable;
boolean isTriggerInsertable;
boolean isTriggerUpdatable;
boolean isTriggerDeletable;
View(Database db, HsqlName name, HsqlName[] columnNames, int check) {
super(db, name, TableBase.VIEW_TABLE);
this.columnNames = columnNames;
this.checkOption = check;
}
public int getType() {
return SchemaObject.VIEW;
}
public OrderedHashSet getReferences() {
return schemaObjectNames;
}
public OrderedHashSet getComponents() {
return null;
}
public void compile(Session session, SchemaObject parentObject) {
ParserDQL p = new ParserDQL(session, new Scanner(session, statement),
null);
p.isViewDefinition = true;
p.read();
TableDerived viewSubQueryTable = p.XreadViewSubqueryTable(this, true);
queryExpression = viewSubQueryTable.queryExpression;
if (getColumnCount() == 0) {
if (columnNames == null) {
columnNames =
viewSubQueryTable.queryExpression.getResultColumnNames();
}
if (columnNames.length
!= viewSubQueryTable.queryExpression.getColumnCount()) {
throw Error.error(ErrorCode.X_42593, getName().statementName);
}
TableUtil.setColumnsInSchemaTable(
this, columnNames, queryExpression.getColumnTypes());
}
schemaObjectNames = p.compileContext.getSchemaObjectNames();
canRecompile = true;
baseTable = queryExpression.getBaseTable();
if (baseTable == null) {
return;
}
switch (checkOption) {
case SchemaObject.ViewCheckModes.CHECK_NONE :
case SchemaObject.ViewCheckModes.CHECK_LOCAL :
case SchemaObject.ViewCheckModes.CHECK_CASCADE :
break;
default :
throw Error.runtimeError(ErrorCode.U_S0500, "View");
}
}
public String getSQL() {
StringBuilder sb = new StringBuilder(128);
sb.append(Tokens.T_CREATE).append(' ').append(Tokens.T_VIEW);
sb.append(' ');
sb.append(getName().getSchemaQualifiedStatementName()).append(' ');
sb.append('(');
int count = getColumnCount();
for (int j = 0; j < count; j++) {
sb.append(getColumn(j).getName().statementName);
if (j < count - 1) {
sb.append(',');
}
}
sb.append(')').append(' ').append(Tokens.T_AS).append(' ');
sb.append(getStatement());
return sb.toString();
}
public int[] getUpdatableColumns() {
return queryExpression.getBaseTableColumnMap();
}
public boolean isTriggerInsertable() {
return isTriggerInsertable;
}
public boolean isTriggerUpdatable() {
return isTriggerUpdatable;
}
public boolean isTriggerDeletable() {
return isTriggerDeletable;
}
public boolean isInsertable() {
return isTriggerInsertable ? false
: super.isInsertable();
}
public boolean isUpdatable() {
return isTriggerUpdatable ? false
: super.isUpdatable();
}
void addTrigger(TriggerDef td, HsqlName otherName) {
switch (td.operationType) {
case StatementTypes.INSERT :
if (isTriggerInsertable) {
throw Error.error(ErrorCode.X_42538);
}
isTriggerInsertable = true;
break;
case StatementTypes.DELETE_WHERE :
if (isTriggerDeletable) {
throw Error.error(ErrorCode.X_42538);
}
isTriggerDeletable = true;
break;
case StatementTypes.UPDATE_WHERE :
if (isTriggerUpdatable) {
throw Error.error(ErrorCode.X_42538);
}
isTriggerUpdatable = true;
break;
default :
throw Error.runtimeError(ErrorCode.U_S0500, "View");
}
super.addTrigger(td, otherName);
}
void removeTrigger(TriggerDef td) {
switch (td.operationType) {
case StatementTypes.INSERT :
isTriggerInsertable = false;
break;
case StatementTypes.DELETE_WHERE :
isTriggerDeletable = false;
break;
case StatementTypes.UPDATE_WHERE :
isTriggerUpdatable = false;
break;
default :
throw Error.runtimeError(ErrorCode.U_S0500, "View");
}
super.removeTrigger(td);
}
public void setDataReadOnly(boolean value) {
throw Error.error(ErrorCode.X_28000);
}
public int getCheckOption() {
return checkOption;
}
public String getStatement() {
return statement;
}
public void setStatement(String sql) {
statement = sql;
}
public TableDerived newDerivedTable(Session session,
CompileContext baseContext) {
TableDerived td;
ParserDQL p = new ParserDQL(session, new Scanner(), baseContext);
p.compileContext.setCurrentSubquery(tableName);
p.reset(session, statement);
p.read();
td = p.XreadViewSubqueryTable(this, false);
return td;
}
}