⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 hsql是很有名的嵌入式数据库
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* Copyright (c) 1995-2000, The Hypersonic SQL 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 Hypersonic SQL 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 THE HYPERSONIC SQL GROUP,
 * 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.
 *
 * This software consists of voluntary contributions made by many individuals 
 * on behalf of the Hypersonic SQL Group.
 *
 *
 * For work added by the HSQL Development Group:
 *
 * Copyright (c) 2001-2005, 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 java.util.Locale;import org.hsqldb.HsqlNameManager.HsqlName;import org.hsqldb.lib.ArrayUtil;import org.hsqldb.lib.HashMap;import org.hsqldb.lib.HsqlArrayList;import org.hsqldb.lib.IntValueHashMap;import org.hsqldb.store.ValuePool;// fredt@users 20020130 - patch 497872 by Nitin Chauhan - reordering for speed// fredt@users 20020215 - patch 1.7.0 by fredt - support GROUP BY with more than one column// fredt@users 20020215 - patch 1.7.0 by fredt - SQL standard quoted identifiers// fredt@users 20020218 - patch 1.7.0 by fredt - DEFAULT keyword// fredt@users 20020221 - patch 513005 by sqlbob@users - SELECT INTO types// fredt@users 20020425 - patch 548182 by skitt@users - DEFAULT enhancement// thertz@users 20020320 - patch 473613 by thertz - outer join condition bug// fredt@users 20021229 - patch 1.7.2 by fredt - new solution for above// fredt@users 20020420 - patch 523880 by leptipre@users - VIEW support// fredt@users 20020525 - patch 559914 by fredt@users - SELECT INTO logging// tony_lai@users 20021020 - patch 1.7.2 - improved aggregates and HAVING// aggregate functions can now be used in expressions - HAVING supported// kloska@users 20021030 - patch 1.7.2 - ON UPDATE CASCADE// fredt@users 20021112 - patch 1.7.2 by Nitin Chauhan - use of switch// rewrite of the majority of multiple if(){}else{} chains with switch(){}// boucherb@users 20030705 - patch 1.7.2 - prepared statement support// fredt@users 20030819 - patch 1.7.2 - EXTRACT({YEAR | MONTH | DAY | HOUR | MINUTE | SECOND } FROM datetime)// fredt@users 20030820 - patch 1.7.2 - CHAR_LENGTH | CHARACTER_LENGTH | OCTET_LENGTH(string)// fredt@users 20030820 - patch 1.7.2 - POSITION(string IN string)// fredt@users 20030820 - patch 1.7.2 - SUBSTRING(string FROM pos [FOR length])// fredt@users 20030820 - patch 1.7.2 - TRIM({LEADING | TRAILING | BOTH} [<character>] FROM <string expression>)// fredt@users 20030820 - patch 1.7.2 - CASE [expr] WHEN ... THEN ... [ELSE ...] END and its variants// fredt@users 20030820 - patch 1.7.2 - NULLIF(expr,expr)// fredt@users 20030820 - patch 1.7.2 - COALESCE(expr,expr,...)// fredt@users 20031012 - patch 1.7.2 - improved scoping for column names in all areas// boucherb@users 200403xx - patch 1.7.2 - added support for prepared SELECT INTO// boucherb@users 200403xx - doc 1.7.2 - some// thomasm@users 20041001 - patch 1.7.3 - BOOLEAN undefined handling// fredt@users 20050220 - patch 1.8.0 - CAST with precision / scale/* todo: fredt - implement remaining numeric value functions (SQL92 6.6) * * EXTRACT({TIMEZONE_HOUR | TIMEZONE_MINUTE} FROM {datetime | interval}) *//** * Responsible for parsing non-DDL statements. * * Extensively rewritten and extended in successive versions of HSQLDB. * * @author Thomas Mueller (Hypersonic SQL Group) * @version 1.8.0 * @since Hypersonic SQL */class Parser {    private Database  database;    private Tokenizer tokenizer;    private Session   session;    private String    sTable;    private String    sToken;    private Object    oData;    private int       iType;    private int       iToken;    //    private int           subQueryLevel;    private HsqlArrayList subQueryList = new HsqlArrayList();    /**     *  Constructs a new Parser object with the given context.     *     * @param  db the Database instance against which to resolve named     *      database object references     * @param  t the token source from which to parse commands     * @param  session the connected context     */    Parser(Session session, Database db, Tokenizer t) {        database     = db;        tokenizer    = t;        this.session = session;    }    /**     *  Resets this parse context with the given SQL character sequence.     *     * Internal structures are reset as though a new parser were created     * with the given sql and the originally specified database and session     *     * @param a new SQL character sequence to replace the current one     */    void reset(String sql) {        sTable = null;        sToken = null;        oData  = null;        tokenizer.reset(sql);        subQueryList.clear();        subQueryLevel = 0;        parameters.clear();    }    /**     * Tests whether the parsing session has the given write access on the     * given Table object. <p>     *     * @param table the Table object to check     * @param userRight the numeric code of the right to check     * @throws HsqlException if the session user does not have the right     *      or the given Table object is simply not writable (e.g. is a     *      non-updateable View)     */    void checkTableWriteAccess(Table table,                               int userRight) throws HsqlException {        // session level user rights        session.checkReadWrite();        // object level user rights        session.check(table.getName(), userRight);        // object type        if (table.isView()) {            throw Trace.error(Trace.NOT_A_TABLE, table.getName().name);        }        // object readonly        table.checkDataReadOnly();    }    /**     * Parses a comma-separated, right-bracket terminated list of column     * names. <p>     *     * @param db the Database instance whose name manager is to provide the     *      resulting HsqlName objects, when the full argument is true     * @param t the tokenizer representing the character sequence to be parsed     * @param full if true, generate a list of HsqlNames, else a list of     *  String objects     */    static HsqlArrayList getColumnNames(Database db, Tokenizer t,                                        boolean full) throws HsqlException {        HsqlArrayList columns = new HsqlArrayList();        while (true) {            if (full) {                String   token  = t.getSimpleName();                boolean  quoted = t.wasQuotedIdentifier();                HsqlName name   = db.nameManager.newHsqlName(token, quoted);                columns.add(name);            } else {                columns.add(t.getSimpleName());            }            String token = t.getSimpleToken();            if (token.equals(Token.T_COMMA)) {                continue;            }            if (token.equals(Token.T_CLOSEBRACKET)) {                break;            }            t.throwUnexpected();        }        return columns;    }    /**     * The SubQuery objects are added to the end of subquery list.     *     * When parsing the SELECT for a view, optional HsqlName[] array is used     * for view column aliases.     *     */    SubQuery parseSubquery(int brackets, HsqlName[] colNames,                           boolean resolveAll,                           int predicateType) throws HsqlException {        SubQuery sq;        sq = new SubQuery();        subQueryLevel++;        boolean canHaveOrder = predicateType == Expression.VIEW;        boolean limitWithOrder = predicateType == Expression.VIEW                                 || predicateType == Expression.QUERY                                 || predicateType == Expression.IN                                 || predicateType == Expression.ALL                                 || predicateType == Expression.ANY;        Select s = parseSelect(brackets, canHaveOrder, false, limitWithOrder,                               true);        sq.level = subQueryLevel;        subQueryLevel--;        boolean isResolved = s.resolveAll(session, resolveAll);        sq.select     = s;        sq.isResolved = isResolved;        // it's not a problem that this table has not a unique name        HsqlName sqtablename =            database.nameManager.newHsqlName("SYSTEM_SUBQUERY", false);        sqtablename.schema = database.schemaManager.SYSTEM_SCHEMA_HSQLNAME;        Table table = new Table(database, sqtablename, Table.SYSTEM_SUBQUERY);        if (colNames != null) {            if (colNames.length != s.iResultLen) {                throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);            }            for (int i = 0; i < s.iResultLen; i++) {                HsqlName name = colNames[i];                s.exprColumns[i].setAlias(name.name, name.isNameQuoted);            }        } else {            for (int i = 0; i < s.iResultLen; i++) {                String colname = s.exprColumns[i].getAlias();                if (colname == null || colname.length() == 0) {                    // fredt - this does not guarantee the uniqueness of column                    // names but addColumns() will throw if names are not unique.                    colname = "COL_" + String.valueOf(i + 1);                    s.exprColumns[i].setAlias(colname, false);                }            }        }        table.addColumns(s);        boolean uniqueValues = predicateType == Expression.EXISTS                               || predicateType == Expression.IN                               || predicateType == Expression.ALL                               || predicateType == Expression.ANY;        int[] pcol = null;        if (uniqueValues) {            pcol = new int[s.iResultLen];            ArrayUtil.fillSequence(pcol);        }        table.createPrimaryKey(pcol);        sq.table      = table;        sq.uniqueRows = uniqueValues;        subQueryList.add(sq);        return sq;    }    SubQuery getViewSubquery(View v) {        SubQuery sq = v.viewSubQuery;        for (int i = 0; i < v.viewSubqueries.length; i++) {            subQueryList.add(v.viewSubqueries[i]);        }        return sq;    }    /**     *  Constructs and returns a Select object.     *     * @param canHaveOrder whether the SELECT being parsed can have an ORDER BY     * @param canHaveLimit whether LIMIT without ORDER BY is allowed     * @param limitWithOrder whether LIMIT is allowed only with ORDER BY     * @param isMain whether the SELECT being parsed is the first     * select statement in the set     * @return a new Select object     * @throws  HsqlException if a parsing error occurs     */    Select parseSelect(int brackets, boolean canHaveOrder,                       boolean canHaveLimit, boolean limitWithOrder,                       boolean isMain) throws HsqlException {        Select select = new Select();        String token  = tokenizer.getString();        if (canHaveLimit || limitWithOrder) {            if (tokenizer.wasThis(Token.T_LIMIT)                    || tokenizer.wasThis(Token.T_TOP)) {                parseLimit(token, select, false);                token = tokenizer.getString();            }        }        if (tokenizer.wasThis(Token.T_DISTINCT)) {            select.isDistinctSelect = true;        } else if (tokenizer.wasThis(Token.T_ALL)) {}        else {            tokenizer.back();        }        // parse column list        HsqlArrayList vcolumn = new HsqlArrayList();        do {            Expression e = parseExpression();            token = tokenizer.getString();            if (tokenizer.wasThis(Token.T_AS)) {                e.setAlias(tokenizer.getSimpleName(),                           tokenizer.wasQuotedIdentifier());                token = tokenizer.getString();            } else if (tokenizer.wasSimpleName()) {                e.setAlias(token, tokenizer.wasQuotedIdentifier());                token = tokenizer.getString();            }            vcolumn.add(e);        } while (tokenizer.wasThis(Token.T_COMMA));        if (token.equals(Token.T_INTO)) {            boolean getname = true;            token = tokenizer.getString();            if (tokenizer.wasSimpleToken()) {                switch (Token.get(token)) {                    case Token.CACHED :                        select.intoType = Table.CACHED_TABLE;                        break;                    case Token.TEMP :                        select.intoType = Table.TEMP_TABLE;                        break;                    case Token.TEXT :                        select.intoType = Table.TEXT_TABLE;                        break;                    case Token.MEMORY :                        select.intoType = Table.MEMORY_TABLE;                        break;                    default :                        select.intoType = database.getDefaultTableType();                        getname         = false;                        break;                }                if (getname) {                    token = tokenizer.getName();                } else {                    if (!tokenizer.wasName()) {                        tokenizer.throwUnexpected();                    }                }            }            select.sIntoTable = database.nameManager.newHsqlName(token,                    tokenizer.wasQuotedIdentifier());            select.sIntoTable.schema =                session.getSchemaHsqlName(tokenizer.getLongNameFirst());            token = tokenizer.getString();        }        tokenizer.matchThis(Token.T_FROM);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -