Package org.hsqldb

Source Code of org.hsqldb.View

/* Copyright (c) 2001-2010, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


package org.hsqldb;

import org.hsqldb.HsqlNameManager.HsqlName;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.ArraySort;
import org.hsqldb.lib.OrderedHashSet;

// fredt@users 20020420 - patch523880 by leptipre@users - VIEW support - modified
// fredt@users 20031227 - remimplementated as compiled query

/**
* Represents an SQL VIEW based on a query expression
*
* @author leptipre@users
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.0.0
* @since 1.7.0
*/
public class View extends TableDerived {

    SubQuery       viewSubQuery;
    private String statement;

    //
    private HsqlName[] columnNames;

    /**
     * List of subqueries in this view in order of materialization. Last
     * element is the view itself.
     */
    SubQuery[] viewSubqueries;

    /**
     * Names of SCHEMA objects referenced in VIEW
     */
    private OrderedHashSet schemaObjectNames;

    /**
     * check option
     */
    private int check;

    //
    private Table baseTable;

    //
    Expression checkExpression;

    //
    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.check       = check;
    }

    public int getType() {
        return SchemaObject.VIEW;
    }

    public OrderedHashSet getReferences() {
        return schemaObjectNames;
    }

    public OrderedHashSet getComponents() {
        return null;
    }

    /**
     * Compiles the query expression and sets up the columns.
     */
    public void compile(Session session, SchemaObject parentObject) {

        ParserDQL p = new ParserDQL(session, new Scanner(statement));

        p.read();

        viewSubQuery    = p.XreadViewSubquery(this);
        queryExpression = viewSubQuery.queryExpression;

        if (getColumnCount() == 0) {
            if (columnNames == null) {
                columnNames =
                    viewSubQuery.queryExpression.getResultColumnNames();
            }

            if (columnNames.length
                    != viewSubQuery.queryExpression.getColumnCount()) {
                throw Error.error(ErrorCode.X_42593, getName().statementName);
            }

            TableUtil.setColumnsInSchemaTable(
                this, columnNames, queryExpression.getColumnTypes());
        }

        //
        OrderedHashSet set = queryExpression.getSubqueries();

        if (set == null) {
            viewSubqueries = new SubQuery[]{ viewSubQuery };
        } else {
            set.add(viewSubQuery);

            viewSubqueries = new SubQuery[set.size()];

            set.toArray(viewSubqueries);
            ArraySort.sort(viewSubqueries, 0, viewSubqueries.length,
                           viewSubqueries[0]);
        }

        for (int i = 0; i < viewSubqueries.length; i++) {
            if (viewSubqueries[i].parentView == null) {
                viewSubqueries[i].parentView = this;
            }

            viewSubqueries[i].prepareTable(session);
        }

        //
        viewSubQuery.getTable().view       = this;
        viewSubQuery.getTable().columnList = columnList;
        schemaObjectNames = p.compileContext.getSchemaObjectNames();
        baseTable                          = queryExpression.getBaseTable();

        if (baseTable == null) {
            return;
        }

        switch (check) {

            case SchemaObject.ViewCheckModes.CHECK_NONE :
                break;

            case SchemaObject.ViewCheckModes.CHECK_LOCAL :
                checkExpression = queryExpression.getCheckCondition();
                break;

            case SchemaObject.ViewCheckModes.CHECK_CASCADE :
                break;

            default :
                throw Error.runtimeError(ErrorCode.U_S0500, "View");
        }
    }

    public String getSQL() {

        StringBuffer sb = new StringBuffer(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 long getChangeTimestamp() {
        return changeTimestamp;
    }

    public boolean isTriggerInsertable() {
        return isTriggerInsertable;
    }

    public boolean isTriggerUpdatable() {
        return isTriggerUpdatable;
    }

    public boolean isTriggerDeletable() {
        return isTriggerDeletable;
    }

    void addTrigger(TriggerDef td, HsqlName otherName) {

        switch (td.operationType) {

            case StatementTypes.INSERT :
                if (isTriggerInsertable) {
                    throw Error.error(ErrorCode.X_42545);
                }

                isTriggerInsertable = true;
                break;

            case StatementTypes.DELETE_WHERE :
                if (isTriggerDeletable) {
                    throw Error.error(ErrorCode.X_42545);
                }

                isTriggerDeletable = true;
                break;

            case StatementTypes.UPDATE_WHERE :
                if (isTriggerUpdatable) {
                    throw Error.error(ErrorCode.X_42545);
                }

                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 :
                isTriggerInsertable = false;
                break;

            default :
                throw Error.runtimeError(ErrorCode.U_S0500, "View");
        }

        super.removeTrigger(td);
    }

    public int getCheckOption() {
        return check;
    }

    /**
     * Returns the query expression for the view.
     */
    public String getStatement() {
        return statement;
    }

    public void setStatement(String sql) {
        statement = sql;
    }

    /**
     * Overridden to disable SET TABLE READONLY DDL for View objects.
     */
    public void setDataReadOnly(boolean value) {
        throw Error.error(ErrorCode.X_28000);
    }

    public void collectAllFunctionExpressions(OrderedHashSet collector) {

        // filter schemaObjectNames
    }

    public Table getSubqueryTable() {
        return viewSubQuery.getTable();
    }

    public SubQuery[] getSubqueries() {
        return viewSubqueries;
    }
}
TOP

Related Classes of org.hsqldb.View

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.