Package org.hsqldb

Source Code of org.hsqldb.ParserCommand

/* Copyright (c) 2001-2009, 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.lib.ArrayUtil;
import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.lib.HsqlList;
import org.hsqldb.lib.OrderedHashSet;
import org.hsqldb.persist.HsqlDatabaseProperties;
import org.hsqldb.scriptio.ScriptWriterBase;
import org.hsqldb.store.ValuePool;
import org.hsqldb.types.Type;

/**
* Parser for session and management statements
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 1.9.0
* @since 1.9.0
*/
public class ParserCommand extends ParserDDL {

    ParserCommand(Session session, Scanner t) {
        super(session, t);
    }

    Statement compileStatement() {

        Statement cs = compilePart();

        if (token.tokenType == Tokens.X_ENDPARSE) {
            if (cs.getSchemalName() == null) {
                cs.setSchemaHsqlName(session.getCurrentSchemaHsqlName());
            }

            return cs;
        }

        throw unexpectedToken();
    }

    HsqlArrayList compileStatements(String sql, int returnType) {

        HsqlArrayList list = new HsqlArrayList();
        Statement     cs   = null;

        reset(sql);

        while (true) {
            if (token.tokenType == Tokens.X_ENDPARSE) {
                break;
            }

            compileContext.reset();

            cs = compilePart();

            if (cs == null) {
                list.add(cs);
            } else {
                list.add(cs);
            }
        }

        if (returnType != StatementTypes.RETURN_ANY) {
            int group = cs.getGroup();

            if (group == StatementTypes.X_SQL_DATA) {
                if (returnType == StatementTypes.RETURN_COUNT) {
                    throw Error.error(ErrorCode.X_07503);
                }
            } else if (returnType == StatementTypes.RETURN_RESULT) {
                throw Error.error(ErrorCode.X_07504);
            }
        }

        return list;
    }

    private Statement compilePart() {

        Statement cs = null;

        setParsePosition(getPosition());

        if (token.tokenType == Tokens.X_STARTPARSE) {
            read();
        }

        switch (token.tokenType) {

            // DQL
            case Tokens.WITH :
            case Tokens.OPENBRACKET :
            case Tokens.VALUES :
            case Tokens.TABLE :
            case Tokens.SELECT : {
                cs = compileCursorSpecification();

                break;
            }

            // DML
            case Tokens.INSERT : {
                cs = compileInsertStatement(RangeVariable.emptyArray);

                break;
            }
            case Tokens.UPDATE : {
                cs = compileUpdateStatement(RangeVariable.emptyArray);

                break;
            }
            case Tokens.MERGE : {
                cs = compileMergeStatement(RangeVariable.emptyArray);

                break;
            }
            case Tokens.DELETE : {
                cs = compileDeleteStatement(RangeVariable.emptyArray);

                break;
            }
            case Tokens.TRUNCATE : {
                cs = compileDeleteStatement(RangeVariable.emptyArray);

                break;
            }

            // PROCEDURE
            case Tokens.CALL : {
                cs = compileCallStatement(
                    session.sessionContext.sessionVariablesRange, false);

                break;
            }

            // SQL SESSION
            case Tokens.SET :
                cs = compileSet();
                break;

            case Tokens.START :
                cs = compileStartTransaction();
                break;

            case Tokens.COMMIT :
                cs = compileCommit();
                break;

            case Tokens.ROLLBACK :
                cs = compileRollback();
                break;

            case Tokens.SAVEPOINT :
                cs = compileSavepoint();
                break;

            case Tokens.RELEASE :
                cs = compileReleaseSavepoint();
                break;

            // DDL
            case Tokens.CREATE :
                cs = compileCreate();
                break;

            case Tokens.ALTER :
                cs = compileAlter();
                break;

            case Tokens.DROP :
                cs = compileDrop();
                break;

            case Tokens.GRANT :
            case Tokens.REVOKE :
                cs = compileGrantOrRevoke();
                break;

            // HSQL SESSION
            case Tokens.LOCK :
                cs = compileLock();
                break;

            case Tokens.CONNECT :
                cs = compileConnect();
                break;

            case Tokens.DISCONNECT :
                cs = compileDisconnect();
                break;

            // HSQL COMMAND
            case Tokens.SCRIPT :
                cs = compileScript();
                break;

            case Tokens.SHUTDOWN :
                cs = compileShutdown();
                break;

            case Tokens.BACKUP :
                cs = compileBackup();
                break;

            case Tokens.CHECKPOINT :
                cs = compileCheckpoint();
                break;

            case Tokens.EXPLAIN :
                cs = compileExplainPlan();
                break;

            case Tokens.DECLARE :
                cs = compileSessionVariableDeclaration();
                break;

            default :
                throw unexpectedToken();
        }

        if (cs.type != StatementTypes.SET_SESSION_AUTHORIZATION) {
            cs.setSQL(getLastPart());
        }

        if (token.tokenType == Tokens.SEMICOLON) {
            read();
        } else if (token.tokenType == Tokens.X_ENDPARSE) {}

        return cs;
    }

    private Statement compileSessionVariableDeclaration() {

        ColumnSchema variable = readLocalVariableDeclarationOrNull();
        Object[]     args     = new Object[]{ variable };
        Statement cs = new StatementSession(StatementTypes.DECLARE_VARIABLE,
                                            args);

        return cs;
    }

    private Statement compileScript() {

        String name = null;

        read();

        if (token.tokenType == Tokens.X_VALUE) {
            if (token.dataType.typeCode != Types.SQL_CHAR) {
                throw Error.error(ErrorCode.X_42581);
            }

            name = token.tokenString;

            read();
        }

        Object[] args = new Object[]{ name };
        Statement cs = new StatementCommand(StatementTypes.DATABASE_SCRIPT,
                                            args, database.getCatalogName(),
                                            null);

        return cs;
    }

    private Statement compileConnect() {

        String userName;
        String password = null;

        read();
        readThis(Tokens.USER);
        checkIsSimpleName();

        userName = token.tokenString;

        read();
        readThis(Tokens.PASSWORD);

        password = readPassword();

        Expression[] args = new Expression[] {
            new ExpressionValue(userName, Type.SQL_VARCHAR),
            new ExpressionValue(password, Type.SQL_VARCHAR)
        };
        Statement cs =
            new StatementSession(StatementTypes.SET_SESSION_AUTHORIZATION,
                                 args);

        return cs;
    }

    private Statement compileSetDefault() {

        read();

        switch (token.tokenType) {

            case Tokens.INITIAL : {
                read();
                readThis(Tokens.SCHEMA);

                HsqlName schema = database.schemaManager.getSchemaHsqlName(
                    token.tokenString);

                read();

                Object[] args = new Object[]{ schema };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_DEFAULT_INITIAL_SCHEMA, args,
                    null, null);
            }
            case Tokens.RESULT : {
                read();
                readThis(Tokens.MEMORY);
                readThis(Tokens.SIZE);

                int      size = readInteger();
                Object[] args = new Object[]{ new Integer(size) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_RESULT_MEMORY_ROWS, args,
                    null, null);
            }
            case Tokens.TABLE : {
                read();
                readThis(Tokens.TYPE);

                int type = TableBase.MEMORY_TABLE;

                switch (token.tokenType) {

                    case Tokens.MEMORY :
                        break;

                    case Tokens.CACHED :
                        type = TableBase.CACHED_TABLE;
                        break;

                    default :
                        throw unexpectedToken();
                }

                read();

                Object[] args = new Object[]{ Integer.valueOf(type) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE, args,
                    null, null);
            }
            default :
                throw unexpectedToken();
        }
    }

    private Statement compileSetProperty() {

        read();

        String                 property;
        Object                 value;
        HsqlDatabaseProperties props;

        checkIsSimpleName();
        checkIsDelimitedIdentifier();

        property = token.tokenString;
        props    = database.getProperties();

        boolean isboolean  = props.isBoolean(token.tokenString);
        boolean isintegral = props.isIntegral(token.tokenString);
        boolean isstring   = props.isString(token.tokenString);

        if (!(isboolean || isintegral || isstring)) {
            throw Error.error(ErrorCode.X_42511);
        }

        int typeCode = isboolean ? Types.SQL_BOOLEAN
                                 : isintegral ? Types.SQL_INTEGER
                                              : Types.SQL_CHAR;

        read();

        if (token.tokenType == Tokens.TRUE) {
            value = Boolean.TRUE;
        } else if (token.tokenType == Tokens.FALSE) {
            value = Boolean.FALSE;
        } else {
            checkIsValue();

            value = token.tokenValue;

            if (token.dataType.typeCode != typeCode) {
                throw Error.error(ErrorCode.X_42565, token.tokenString);
            }
        }

        read();

        Object[] args = new Object[] {
            property, value
        };

        return new StatementCommand(StatementTypes.SET_DATABASE_PROPERTY,
                                    args, null, null);
    }

    private Statement compileSet() {

        int position = super.getPosition();

        session.setScripting(false);
        read();

        switch (token.tokenType) {

            case Tokens.SCHEMA : {
                read();

                Expression e = XreadValueSpecificationOrNull();

                if (e == null) {
                    HsqlName name = readSchemaName();
                    Object[] args = new Object[]{ name };

                    return new StatementSession(StatementTypes.SET_SCHEMA,
                                                args);
                }

                if (!e.getDataType().isCharacterType()) {
                    throw Error.error(ErrorCode.X_0P000);
                }

                if (e.getType() != OpTypes.VALUE
                        && (e.getType() != OpTypes.SQL_FUNCTION
                            || !((FunctionSQL) e).isValueFunction())) {
                    throw Error.error(ErrorCode.X_0P000);
                }

                Expression[] args = new Expression[]{ e };

                return new StatementSession(StatementTypes.SET_SCHEMA, args);
            }
            case Tokens.TIME : {
                read();

                return compileSetTimeZone();
            }
            case Tokens.ROLE : {
                read();

                return compileSetRole();
            }
            case Tokens.SESSION : {
                read();

                return compileSessionSettings();
            }
            case Tokens.TRANSACTION : {
                read();

                Object[] args = processTransactionCharacteristics();

                if (args[0] == null && args[1] == null) {
                    throw unexpectedToken();
                }

                return new StatementSession(StatementTypes.SET_TRANSACTION,
                                            args);
            }
            case Tokens.AUTOCOMMIT : {
                read();

                boolean  mode = processTrueOrFalse();
                Object[] args = new Object[]{ Boolean.valueOf(mode) };

                return new StatementSession(
                    StatementTypes.SET_SESSION_AUTOCOMMIT, args);
            }

            // deprecated
            case Tokens.READONLY : {
                read();

                boolean  readonly = processTrueOrFalse();
                Object[] args     = new Object[]{ Boolean.valueOf(readonly) };

                return new StatementSession(
                    StatementTypes.SET_SESSION_CHARACTERISTICS, args);
            }
            case Tokens.LOGSIZE : {
                read();
                checkDatabaseUpdateAuthorisation();

                int      size = readInteger();
                Object[] args = new Object[]{ new Integer(size) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_FILES_LOG_SIZE, args, null,
                    null);
            }
            case Tokens.SCRIPTFORMAT : {
                read();
                checkDatabaseUpdateAuthorisation();

                switch (token.tokenType) {

                    case Tokens.TEXT :
                    case Tokens.BINARY :
                    case Tokens.COMPRESSED :
                        break;

                    default :
                        throw unexpectedToken();
                }

                int mode = ArrayUtil.find(ScriptWriterBase.LIST_SCRIPT_FORMATS,
                                          token.tokenString);

                if (mode == 0 || mode == 1 || mode == 3) {}
                else {
                    throw unexpectedToken();
                }

                read();

                Object[] args = new Object[]{ new Integer(mode) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_SCRIPT_FORMAT, args,
                    database.getCatalogName(), null);
            }
            case Tokens.IGNORECASE : {
                read();

                boolean  mode = processTrueOrFalse();
                Object[] args = new Object[]{ Boolean.valueOf(mode) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_SQL_IGNORECASE, args, null,
                    null);
            }
            case Tokens.MAXROWS : {
                read();

                int      size = readInteger();
                Object[] args = new Object[]{ new Integer(size) };

                return new StatementSession(
                    StatementTypes.SET_SESSION_RESULT_MAX_ROWS, args);
            }

            // for backward compatibility
            case Tokens.DEFAULT : {
                read();
                readThis(Tokens.TABLE);
                readThis(Tokens.TYPE);

                int type = TableBase.MEMORY_TABLE;

                switch (token.tokenType) {

                    case Tokens.MEMORY :
                        break;

                    case Tokens.CACHED :
                        type = TableBase.CACHED_TABLE;
                        break;

                    default :
                        throw unexpectedToken();
                }

                read();

                Object[] args = new Object[]{ Integer.valueOf(type) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE, args,
                    null, null);
            }
            case Tokens.RESULT : {
                read();
                readThis(Tokens.MEMORY);
                readThis(Tokens.SIZE);

                int      size = readInteger();
                Object[] args = new Object[]{ new Integer(size) };

                return new StatementSession(
                    StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS, args);
            }
            case Tokens.TABLE : {
                read();

                Table    t    = readTableName();
                Object[] args = new Object[] {
                    t.tableName, null
                };

                switch (token.tokenType) {

                    default : {
                        throw unexpectedToken();
                    }
                    case Tokens.SOURCE :
                        read();

                        return compileTextTableSource(t);

                    case Tokens.READ : {
                        read();

                        boolean readonly = false;

                        if (token.tokenType == Tokens.WRITE) {}
                        else {
                            readThis(Tokens.ONLY);

                            readonly = true;
                        }

                        args[1] = Boolean.valueOf(readonly);

                        return new StatementCommand(
                            StatementTypes.SET_TABLE_READONLY, args, null,
                            t.getName());
                    }

                    // deprecated
                    case Tokens.READONLY : {
                        read();

                        boolean readonly = processTrueOrFalse();

                        args[1] = Boolean.valueOf(readonly);

                        return new StatementCommand(
                            StatementTypes.SET_TABLE_READONLY, args, null,
                            t.getName());
                    }
                    case Tokens.INDEX : {
                        String value;

                        read();
                        checkIsValue();

                        value = token.tokenString;

                        read();

                        args[1] = value;

                        return new StatementCommand(
                            StatementTypes.SET_TABLE_INDEX, args, null, null);
                    }
                    case Tokens.TYPE : {
                        read();

                        int newType;

                        if (token.tokenType == Tokens.CACHED) {
                            newType = TableBase.CACHED_TABLE;
                        } else if (token.tokenType == Tokens.MEMORY) {
                            newType = TableBase.MEMORY_TABLE;
                        } else {
                            throw Error.error(ErrorCode.X_42581);
                        }

                        read();

                        args[1] = new Integer(newType);

                        return new StatementCommand(
                            StatementTypes.SET_TABLE_TYPE, args, null,
                            t.getName());
                    }
                }
            }
            case Tokens.CHECKPOINT : {
                read();
                readThis(Tokens.DEFRAG);

                int      size = readInteger();
                Object[] args = new Object[]{ new Integer(size) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_FILES_DEFRAG, args, null,
                    null);
            }
            case Tokens.WRITE_DELAY : {
                read();

                int delay = 0;

                if (token.tokenType == Tokens.TRUE) {
                    delay = database.getProperties().getDefaultWriteDelay();

                    read();
                } else if (token.tokenType == Tokens.FALSE) {
                    delay = 0;

                    read();
                } else {
                    delay = this.readInteger();

                    if (delay < 0) {
                        delay = 0;
                    }

                    if (token.tokenType == Tokens.MILLIS) {
                        read();
                    } else {
                        delay *= 1000;
                    }
                }

                Object[] args = new Object[]{ new Integer(delay) };

                return new StatementCommand(
                    StatementTypes.SET_DATABASE_FILES_WRITE_DELAY, args, null,
                    null);
            }
            case Tokens.PASSWORD : {
                String password;

                read();

                password = readPassword();

                Object[] args = new Object[] {
                    null, password
                };

                return new StatementCommand(StatementTypes.SET_USER_PASSWORD,
                                            args, null, null);
            }
            case Tokens.INITIAL : {
                read();
                readThis(Tokens.SCHEMA);

                HsqlName schema;

                if (token.tokenType == Tokens.DEFAULT) {
                    schema = null;
                } else {
                    schema = database.schemaManager.getSchemaHsqlName(
                        token.tokenString);
                }

                read();

                Object[] args = new Object[] {
                    null, schema
                };

                return new StatementCommand(
                    StatementTypes.SET_USER_INITIAL_SCHEMA, args, null, null);
            }
            case Tokens.DATABASE : {
                read();

                String name;

                switch (token.tokenType) {

                    case Tokens.BACKUP : {
                        read();
                        checkDatabaseUpdateAuthorisation();
                        readThis(Tokens.INCREMENT);

                        boolean  flag = processTrueOrFalse();
                        Object[] args = new Object[]{ Boolean.valueOf(flag) };

                        return new StatementCommand(
                            StatementTypes.SET_DATABASE_FILES_BACKUP_INCREMENT,
                            args, database.getCatalogName(), null);
                    }
                    case Tokens.COLLATION : {
                        read();
                        checkIsSimpleName();

                        name = token.tokenString;

                        read();

                        Object[] args = new Object[]{ name };

                        return new StatementCommand(
                            StatementTypes.SET_DATABASE_SQL_COLLATION, args,
                            null, null);
                    }
                    case Tokens.DEFAULT : {
                        return compileSetDefault();
                    }
                    case Tokens.EVENT : {
                        read();
                        readThis(Tokens.LOG);
                        readThis(Tokens.LEVEL);

                        int      value = readInteger();
                        Object[] args = new Object[]{ Integer.valueOf(value) };

                        return new StatementCommand(
                            StatementTypes.SET_DATABASE_FILES_EVENT_LOG, args,
                            null, null);
                    }
                    case Tokens.FILES : {
                        read();

                        int     type  = 0;
                        boolean flag  = false;
                        int     value = 0;

                        switch (token.tokenType) {

                            case Tokens.LOCK : {
                                read();

                                flag = processTrueOrFalse();
                                type = StatementTypes.SET_DATABASE_FILES_LOCK;

                                break;
                            }
                            case Tokens.READ : {
                                read();

                                type = StatementTypes
                                    .SET_DATABASE_FILES_READ_ONLY;

                                if (readIfThis(Tokens.ONLY)) {
                                    flag = true;
                                } else {
                                    readThis(Tokens.WRITE);

                                    flag = false;
                                }

                                if (readIfThis(Tokens.FILES)) {
                                    type = StatementTypes
                                        .SET_DATABASE_FILES_READ_ONLY_FILES;
                                }

                                flag = processTrueOrFalse();

                                break;
                            }
                            case Tokens.CACHE : {
                                read();

                                if (readIfThis(Tokens.SIZE)) {
                                    value = readInteger();
                                    type = StatementTypes
                                        .SET_DATABASE_FILES_CACHE_SIZE;
                                } else if (readIfThis(Tokens.ROWS)) {
                                    value = readInteger();
                                    type = StatementTypes
                                        .SET_DATABASE_FILES_CACHE_FILE_SCALE;
                                } else if (readIfThis(Tokens.FILE)) {
                                    readThis(Tokens.SCALE);

                                    value = readInteger();
                                    type = StatementTypes
                                        .SET_DATABASE_FILES_CACHE_FILE_SCALE;
                                }

                                break;
                            }
                            case Tokens.DEFRAG : {
                                read();

                                type = StatementTypes
                                    .SET_DATABASE_FILES_DEFRAG;
                                value = readInteger();

                                break;
                            }
                            case Tokens.NIO : {
                                read();

                                type = StatementTypes.SET_DATABASE_FILES_NIO;
                                flag = processTrueOrFalse();

                                break;
                            }
                            default :
                                unexpectedToken();
                        }

                        Object[] args = new Object[] {
                            new Integer(value), Boolean.valueOf(flag)
                        };

                        return new StatementCommand(type, args, null, null);
                    }
                    case Tokens.REFERENTIAL_INTEGRITY : {
                        read();

                        boolean  mode = processTrueOrFalse();
                        Object[] args = new Object[]{ Boolean.valueOf(mode) };

                        return new StatementCommand(
                            StatementTypes
                                .SET_DATABASE_SQL_REFERENTIAL_INTEGRITY, args,
                                    null, null);
                    }
                    case Tokens.TRANSACTION : {
                        read();
                        readThis(Tokens.CONTROL);

                        boolean mvcc = false;

                        if (token.tokenType == Tokens.MVCC) {
                            read();

                            mvcc = true;
                        } else {
                            readThis(Tokens.LOCKS);
                        }

                        Object[] args = new Object[]{ Boolean.valueOf(mvcc) };

                        return new StatementCommand(
                            StatementTypes.SET_DATABASE_TRANSACTION_CONTROL,
                            args, null, null);
                    }
                    case Tokens.PROPERTY : {
                        return compileSetProperty();
                    }
                    default : {
                        throw unexpectedToken();
                    }
                }
            }
            case Tokens.PROPERTY : {
                return compileSetProperty();
            }
            default : {
                rewind(position);

                return compileSetStatement(
                    session.sessionContext.sessionVariablesRange);
            }
        }
    }

    Object[] processTransactionCharacteristics() {

        int      level    = 0;
        boolean  readonly = false;
        Object[] args     = new Object[2];

        outerloop:
        while (true) {
            switch (token.tokenType) {

                case Tokens.READ : {
                    if (args[0] != null) {
                        throw unexpectedToken();
                    }

                    read();

                    if (token.tokenType == Tokens.ONLY) {
                        read();

                        readonly = true;
                    } else {
                        readThis(Tokens.WRITE);

                        readonly = false;
                    }

                    args[0] = Boolean.valueOf(readonly);

                    break;
                }
                case Tokens.ISOLATION : {
                    if (args[1] != null) {
                        throw unexpectedToken();
                    }

                    read();
                    readThis(Tokens.LEVEL);

                    switch (token.tokenType) {

                        case Tokens.SERIALIZABLE :
                            read();

                            level = SessionInterface.TX_SERIALIZABLE;
                            break;

                        case Tokens.READ :
                            read();

                            if (token.tokenType == Tokens.COMMITTED) {
                                read();

                                level = SessionInterface.TX_READ_COMMITTED;
                            } else if (token.tokenType == Tokens.UNCOMMITTED) {
                                read();

                                level = SessionInterface.TX_READ_UNCOMMITTED;
                            } else {
                                throw unexpectedToken();
                            }
                            break;

                        case Tokens.REPEATABLE :
                            read();
                            readThis(Tokens.READ);

                            level = SessionInterface.TX_REPEATABLE_READ;
                            break;

                        default :
                            throw unexpectedToken();
                    }

                    args[1] = new Integer(level);

                    break;
                }
                default : {
                    break outerloop;
                }
            }
        }

        if (!readonly && level == 1) {
            throw unexpectedToken(Tokens.T_WRITE);
        }

        return args;
    }

    /**
     * Retrieves boolean value corresponding to the next token.
     *
     * @return   true if next token is "TRUE"; false if next token is "FALSE"
     * @throws  HsqlException if the next token is neither "TRUE" or "FALSE"
     */
    private boolean processTrueOrFalse() {

        if (token.tokenType == Tokens.TRUE) {
            read();

            return true;
        } else if (token.tokenType == Tokens.FALSE) {
            read();

            return false;
        } else {
            throw unexpectedToken();
        }
    }

    /**
     * Responsible for  handling the execution of COMMIT [WORK]
     *
     * @throws  HsqlException
     */
    private Statement compileCommit() {

        boolean chain = false;

        read();
        readIfThis(Tokens.WORK);

        if (token.tokenType == Tokens.AND) {
            read();

            if (token.tokenType == Tokens.NO) {
                read();
            } else {
                chain = true;
            }

            readThis(Tokens.CHAIN);
        }

        String    sql  = getLastPart();
        Object[]  args = new Object[]{ Boolean.valueOf(chain) };
        Statement cs = new StatementSession(StatementTypes.COMMIT_WORK, args);

        return cs;
    }

    private Statement compileStartTransaction() {

        read();
        readThis(Tokens.TRANSACTION);

        Object[] args = processTransactionCharacteristics();
        Statement cs = new StatementSession(StatementTypes.START_TRANSACTION,
                                            args);

        return cs;
    }

    private Statement compileLock() {

        read();
        readThis(Tokens.TABLE);

        OrderedHashSet readSet  = new OrderedHashSet();
        OrderedHashSet writeSet = new OrderedHashSet();

        outerloop:
        while (true) {
            Table table = readTableName();

            switch (token.tokenType) {

                case Tokens.READ :
                    read();
                    readSet.add(table.getName());
                    break;

                case Tokens.WRITE :
                    read();
                    writeSet.add(table.getName());
                    break;

                default :
                    throw unexpectedToken();
            }

            if (token.tokenType == Tokens.COMMA) {
                read();

                continue;
            }

            break outerloop;
        }

        HsqlName[] readTableNames = new HsqlName[readSet.size()];

        readSet.toArray(readTableNames);

        HsqlName[] writeTableNames = new HsqlName[writeSet.size()];

        writeSet.toArray(writeTableNames);

        Statement cs =
            new StatementSession(StatementTypes.TRANSACTION_LOCK_TABLE,
                                 readTableNames, writeTableNames);

        return cs;
    }

    private Statement compileRollback() {

        boolean chain     = false;
        String  savepoint = null;

        read();

        if (token.tokenType == Tokens.TO) {
            read();
            readThis(Tokens.SAVEPOINT);
            checkIsSimpleName();

            savepoint = token.tokenString;

            read();

            String   sql  = getLastPart();
            Object[] args = new Object[]{ savepoint };
            Statement cs =
                new StatementSession(StatementTypes.ROLLBACK_SAVEPOINT, args);

            return cs;
        } else {
            if (token.tokenType == Tokens.WORK) {
                read();
            }

            if (token.tokenType == Tokens.AND) {
                read();

                if (token.tokenType == Tokens.NO) {
                    read();
                } else {
                    chain = true;
                }

                readThis(Tokens.CHAIN);
            }
        }

        String   sql  = getLastPart();
        Object[] args = new Object[]{ Boolean.valueOf(chain) };
        Statement cs = new StatementSession(StatementTypes.ROLLBACK_WORK,
                                            args);

        return cs;
    }

    private Statement compileSavepoint() {

        String name;

        read();
        checkIsSimpleName();

        name = token.tokenString;

        read();

        String   sql  = getLastPart();
        Object[] args = new Object[]{ name };

        return new StatementSession(StatementTypes.SAVEPOINT, args);
    }

    private Statement compileReleaseSavepoint() {

        read();
        readThis(Tokens.SAVEPOINT);

        String name = token.tokenString;

        read();

        String   sql  = getLastPart();
        Object[] args = new Object[]{ name };

        return new StatementSession(StatementTypes.RELEASE_SAVEPOINT, args);
    }

    private Statement compileSessionSettings() {

        if (token.tokenType == Tokens.CHARACTERISTICS) {
            read();
            readThis(Tokens.AS);

            Object[] args = processTransactionCharacteristics();

            return new StatementSession(
                StatementTypes.SET_SESSION_CHARACTERISTICS, args);
        } else if (token.tokenType == Tokens.AUTHORIZATION) {
            read();

            Expression e = XreadValueSpecificationOrNull();

            if (e == null) {
                throw Error.error(ErrorCode.X_42584);
            }

            e.resolveTypes(session, null);

            if (e.isParam()) {
                e.dataType = Type.SQL_VARCHAR;
            }

            if (e.dataType == null || !e.dataType.isCharacterType()) {
                throw Error.error(ErrorCode.X_42565);
            }

            Expression[] args = new Expression[] {
                e, null
            };

            return new StatementSession(
                StatementTypes.SET_SESSION_AUTHORIZATION, args);
        }

        throw unexpectedToken();
    }

    private Statement compileSetRole() {

        Expression e;

        if (token.tokenType == Tokens.NONE) {
            read();

            e = new ExpressionOp(null, Type.SQL_VARCHAR);
        } else {
            e = XreadValueSpecificationOrNull();

            if (e == null) {
                throw Error.error(ErrorCode.X_2A000);
            }

            if (!e.getDataType().isCharacterType()) {
                throw Error.error(ErrorCode.X_0P000);
            }

            if (e.getType() != OpTypes.VALUE
                    && (e.getType() != OpTypes.SQL_FUNCTION
                        || !((FunctionSQL) e).isValueFunction())) {
                throw Error.error(ErrorCode.X_0P000);
            }
        }

        String sql = getLastPart();

        return new StatementSession(StatementTypes.SET_ROLE,
                                    new Expression[]{ e });
    }

    private Statement compileSetTimeZone() {

        Expression e;

        readThis(Tokens.ZONE);

        if (token.tokenType == Tokens.LOCAL) {
            read();

            e = new ExpressionValue(null, Type.SQL_VARCHAR);
        } else {
            e = XreadIntervalValueExpression();

            HsqlList unresolved =
                e.resolveColumnReferences(RangeVariable.emptyArray, null);

            ExpressionColumn.checkColumnsResolved(unresolved);
            e.resolveTypes(session, null);

            if (e.dataType == null) {
                throw Error.error(ErrorCode.X_42565);
            }

            if (e.dataType.typeCode != Types.SQL_INTERVAL_HOUR_TO_MINUTE) {
                throw Error.error(ErrorCode.X_42565);
            }
        }

        String sql = getLastPart();

        return new StatementSession(StatementTypes.SET_TIME_ZONE,
                                    new Expression[]{ e });
    }

    private Statement compileShutdown() {

        int closemode;

        session.checkAdmin();

        closemode = Database.CLOSEMODE_NORMAL;

        read();

        switch (token.tokenType) {

            case Tokens.IMMEDIATELY :
                closemode = Database.CLOSEMODE_IMMEDIATELY;

                read();
                break;

            case Tokens.COMPACT :
                closemode = Database.CLOSEMODE_COMPACT;

                read();
                break;

            case Tokens.SCRIPT :
                closemode = Database.CLOSEMODE_SCRIPT;

                read();
                break;

            // only semicolon is accepted here
        }

        if (token.tokenType == Tokens.SEMICOLON) {
            read();
        }

        if (token.tokenType != Tokens.X_ENDPARSE) {
            throw unexpectedToken();
        }

        String   sql  = getLastPart();
        Object[] args = new Object[]{ new Integer(closemode) };
        Statement cs = new StatementCommand(StatementTypes.DATABASE_SHUTDOWN,
                                            args, null, null);

        return cs;
    }

    private Statement compileBackup() {

        read();
        readThis(Tokens.DATABASE);
        readThis(Tokens.TO);
        checkIsValue();
        readQuotedString();

        String path = token.tokenString;

        read();

        Boolean blockingMode = null;    // Default to non-blocking
        Boolean scriptMode   = null;    // Default to non-script
        Boolean compression  = null;    // Defaults to compressed

        outerLoop:
        while (true) {
            switch (token.tokenType) {

                case Tokens.BLOCKING :
                    if (blockingMode != null) {
                        throw unexpectedToken();
                    }

                    blockingMode = Boolean.TRUE;

                    read();
                    break;

                case Tokens.SCRIPT :
                    if (scriptMode != null) {
                        throw unexpectedToken();
                    }

                    scriptMode = Boolean.TRUE;

                    read();
                    break;

                case Tokens.COMPRESSED :
                    if (compression != null) {
                        throw unexpectedToken();
                    }

                    compression = Boolean.TRUE;

                    read();
                    break;

                case Tokens.NOT :
                    read();

                    if (token.tokenType == Tokens.COMPRESSED) {
                        if (compression != null) {
                            throw unexpectedToken();
                        }

                        compression = Boolean.FALSE;

                        read();
                    } else if (token.tokenType == Tokens.BLOCKING) {
                        blockingMode = Boolean.FALSE;

                        read();
                    } else {
                        throw unexpectedToken();
                    }
                    break;

                default :
                    break outerLoop;
            }
        }

        /**
         * @todo: This block is TEMPORARY.  Will be removed when we implement
         * Non-Blocking and SCRIPT mode.
         */
        if (scriptMode != null) {
            throw unsupportedFeature("SCRIPT");
        }

        scriptMode = Boolean.FALSE;

        if (blockingMode == null) {
            throw unexpectedTokenRequire("BLOCKING");
        }

        if (compression == null) {
            compression = Boolean.TRUE;
        }

        return new StatementCommand(StatementTypes.DATABASE_BACKUP,
                                    new Object[] {
            path, blockingMode, scriptMode, compression,
        }, null, null);
    }

    private Statement compileCheckpoint() {

        boolean defrag = false;

        read();

        if (token.tokenType == Tokens.DEFRAG) {
            defrag = true;

            read();
        } else if (token.tokenType == Tokens.SEMICOLON) {
            read();

            // only semicolon is accepted here
        }

        if (token.tokenType != Tokens.X_ENDPARSE) {
            throw unexpectedToken();
        }

        String   sql       = getLastPart();
        Object[] args      = new Object[]{ Boolean.valueOf(defrag) };
        HsqlName writeName = defrag ? database.getCatalogName()
                                    : null;
        Statement cs = new StatementCommand(StatementTypes.DATABASE_CHECKPOINT,
                                            args, database.getCatalogName(),
                                            writeName);

        return cs;
    }

    private Statement compileDisconnect() {

        read();

        String sql = Tokens.T_DISCONNECT;
        Statement cs = new StatementSession(StatementTypes.DISCONNECT,
                                            (Object[]) null);

        return cs;
    }

    private Statement compileExplainPlan() {

        Statement cs;

        read();
        readThis(Tokens.PLAN);
        readThis(Tokens.FOR);

        cs                 = compilePart();
        cs.writeTableNames = HsqlName.emptyArray;
        cs.readTableNames  = HsqlName.emptyArray;

        cs.setDescribe();

        return cs;
    }

    private Statement compileTextTableSource(Table t) {

        boolean  isSourceHeader = false;
        boolean  isDesc         = false;
        String   source;
        Object[] args = new Object[5];

        args[0] = t.tableName;

        if (!t.isText()) {
            Exception e = Error.error(ErrorCode.X_S0522);
        }

        // SET TABLE <table> SOURCE ON
        if (token.tokenType == Tokens.ON) {
            read();

            String sql = getLastPart();

            args[1] = Boolean.TRUE;

            return new StatementCommand(StatementTypes.SET_TABLE_SOURCE, args,
                                        null, t.getName());
        } else if (token.tokenType == Tokens.OFF) {
            read();

            String sql = getLastPart();

            args[1] = Boolean.FALSE;

            return new StatementCommand(StatementTypes.SET_TABLE_SOURCE, args,
                                        null, t.getName());
        } else if (token.tokenType == Tokens.HEADER) {
            read();

            isSourceHeader = true;
        }

        if (token.tokenType != Tokens.X_DELIMITED_IDENTIFIER
                && (token.tokenType != Tokens.X_VALUE
                    || !token.dataType.isCharacterType())) {
            throw Error.error(ErrorCode.X_42581);
        }

        source = token.tokenString;

        read();

        if (!isSourceHeader && token.tokenType == Tokens.DESC) {
            isDesc = true;

            read();
        }

        String sql = getLastPart();

        args[2] = source;
        args[3] = Boolean.valueOf(isDesc);
        args[4] = Boolean.valueOf(isSourceHeader);

        return new StatementCommand(StatementTypes.SET_TABLE_SOURCE, args,
                                    null, t.getName());
    }
}
TOP

Related Classes of org.hsqldb.ParserCommand

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.