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

📄 tablefilter.java

📁 hsqldb是100%java实现的数据库,是一个开放源代码的JAVA数据库 l 具有标准的SQL语法和JAVA接口 l HSQLDB可以自由使用和分发 l 非常简洁和快速的
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* 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 org.hsqldb.index.RowIterator;import org.hsqldb.lib.ArrayUtil;import org.hsqldb.lib.HashMappedList;// fredt@users 20030813 - patch 1.7.2 - fix for column comparison within same table bugs #572075 and 722443// fredt@users 20031012 - patch 1.7.2 - better OUTER JOIN implementation// fredt@users 20031026 - patch 1.7.2 - more efficient findfirst - especially for multi-column equijoins// implemented optimisations similart to patch 465542 by hjbush@users/** * This class iterates over table rows to select the rows that fulfil join * or other conditions. It uses indexes if they are availabe. * * Extended in successive versions of HSQLDB. * * @author Thomas Mueller (Hypersonic SQL Group) * @version 1.8.0 * @since Hypersonic SQL */final class TableFilter {    static final int CONDITION_NONE      = -1;     // not a condition expression    static final int CONDITION_UNORDERED = 0;      // not candidate for eStart or eEnd    static final int   CONDITION_START_END = 1;    // candidate for eStart and eEnd    static final int   CONDITION_START     = 2;    // candidate for eStart    static final int   CONDITION_END       = 3;    // candidate for eEnd    static final int   CONDITION_OUTER     = 4;    // add to this    Table              filterTable;    private String     tableAlias;    HashMappedList     columnAliases;    Index              filterIndex;    private Object[]   emptyData;    boolean[]          usedColumns;    private Expression eStart, eEnd;    //    Expression eAnd;    //    boolean      isOuterJoin;                      // table joined with OUTER JOIN    boolean      isAssigned;                       // conditions have been assigned to this    boolean      isMultiFindFirst;                 // findFirst() uses multi-column index    Expression[] findFirstExpressions;             // expressions for column values    //    private RowIterator it;    Object[]            currentData;    Row                 currentRow;    //    Object[] currentJoinData;    // addendum to the result of findFirst() and next() with isOuterJoin==true    // when the result is false, it indicates if a non-join condition caused the failure    boolean nonJoinIsNull;    // indicates current data is empty data produced for an outer join    boolean isCurrentOuter;    /**     * Constructor declaration     *     *     * @param t     * @param alias     * @param outerjoin     */    TableFilter(Table t, String alias, HashMappedList columnList,                boolean outerjoin) {        filterTable   = t;        tableAlias    = alias == null ? t.getName().name                                      : alias;        columnAliases = columnList;        isOuterJoin   = outerjoin;        emptyData     = filterTable.getEmptyRowData();        usedColumns   = filterTable.getNewColumnCheckList();    }    /**     * Returns the alias or the table name.     * Never returns null;     * @return     */    String getName() {        return tableAlias;    }    /**     * Retrieves this object's filter Table object.     *     * @return this object's filter Table object     */    Table getTable() {        return filterTable;    }    /**     * Retrieves a CONDITION_XXX code indicating how a condition     * expression can be used for a TableFilter.     *     * @param exprType an expression type code     * @return     */    static int getConditionType(Expression e) {        int exprType = e.getType();        switch (exprType) {            case Expression.NOT_EQUAL :            case Expression.LIKE :                return CONDITION_UNORDERED;            case Expression.IN : {                return e.isQueryCorrelated ? CONDITION_NONE                                           : CONDITION_UNORDERED;            }            case Expression.IS_NULL :            case Expression.EQUAL : {                return CONDITION_START_END;            }            case Expression.BIGGER :            case Expression.BIGGER_EQUAL : {                return CONDITION_START;            }            case Expression.SMALLER :            case Expression.SMALLER_EQUAL : {                return CONDITION_END;            }            default : {                // not a condition so forget it                return CONDITION_NONE;            }        }    }    // TODO: Optimize    //    // The current way always chooses eStart, eEnd conditions    // using first encountered eligible index    //    // We should check if current index offers better selectivity/access    // path than previously assigned iIndex.    //    // EXAMPLE 1:    //    // CREATE TABLE t (c1 int, c2 int primary key)    // CREATE INDEX I1 ON t(c1)    // SELECT    //      *    // FROM    //      t    // WHERE    //     c1 = | < | <= | >= | > ...    // AND    //     c2 = | < | <= | >= | > ...    //    // currently always chooses iIndex / condition (c1/I1), over    // index / condition (c2/pk), whereas index / condition (c2/pk)    // may well be better, especially if condition on c2 is equality    // (condition_start_end) and conditionon(s) on c1 involve range    // (condition_start, condition_end, or some composite).    //    // Currently, the developer/client software must somehow know facts    // both about the table, the query and the way HSQLDB forms its    // plans and, based on this knowlege, perhaps decide to reverse    // order by explicitly issuing instead:    //    // SELECT    //      *    // FROM    //      t    // WHERE    //     c2 = | < | <= | >= | > ...    // AND    //     c1 = | < | <= | >= | > ...    //    // to get optimal index choice.    //    // The same thing applies to and is even worse for joins.    //    // Consider the following (highly artificial, but easy to    // understand) case:    //    // CREATE TABLE T1(ID INTEGER PRIMARY KEY, C1 INTEGER)    // CREATE INDEX I1 ON T1(C1)    // CREATE TABLE T2(ID INTEGER PRIMARY KEY, C1 INTEGER)    // CREATE INDEX I2 ON T2(C1)    //    // select * from t1, t2 where t1.c1 = t2.c1 and t1.id = t2.id    //    // Consider the worst value distribution where t1 and t2 are both    // 10,000 rows, c1 selectivity is nil (all values are identical)    // for both tables, and, say, id values span the range 0..9999    // for both tables.    //    // Then time to completion on 500 MHz Athlon testbed using memory    // tables is:    //    // 10000 row(s) in 309114 ms    //    // whereas for:    //    // select * from t1, t2 where t1.id = t2.id and t1.c1 = t2.c1    //    // time to completion is:    //    // 10000 row(s) in 471 ms    //    // Hence, the unoptimized query takes 656 times as long as the    // optimized one!!!    //    // EXAMPLE 2:    //    // If there are, say, two non-unique candidate indexes,    // and some range or equality predicates against    // them, preference should be given to the one with    // better selectivity (if the total row count of the    // table is large, otherwise the overhead of making    // the choice is probably large w.r.t. any possible    // savings).  Might require maintaining some basic    // statistics or performing appropriate index probes    // at the time the plan is being generated.    /**     * Chooses certain query conditions and assigns a copy of them to this     * filter. The original condition is set to Expression.TRUE once assigned.     *     * @param condition     *     * @throws HsqlException     */    void setConditions(Session session,                       Expression condition) throws HsqlException {        setCondition(session, condition);        if (filterIndex == null) {            filterIndex = filterTable.getPrimaryIndex();        }        if (filterIndex.getVisibleColumns() == 1 || eStart == null                || eAnd == null || eStart.exprType != Expression.EQUAL) {            return;        }        boolean[]    check    = filterTable.getNewColumnCheckList();        Expression[] expr     = new Expression[check.length];        int          colindex = eStart.getArg().getColumnNr();        check[colindex] = true;        expr[colindex]  = eStart.getArg2();        eAnd.getEquiJoinColumns(this, check, expr);        if (ArrayUtil.containsAllTrueElements(check, filterIndex.colCheck)) {            isMultiFindFirst     = true;            findFirstExpressions = expr;        }    }    private void setCondition(Session session,                              Expression e) throws HsqlException {        int        type = e.getType();        Expression e1   = e.getArg();        Expression e2   = e.getArg2();        isAssigned = true;        if (type == Expression.AND) {            setCondition(session, e1);            setCondition(session, e2);            return;        }        if (type == Expression.OR && isOuterJoin && e.isInJoin                && e.outerFilter == this) {            addAndCondition(e);            e.setTrue();            return;        }        int conditionType = getConditionType(e);        if (conditionType == CONDITION_NONE) {            // not a condition expression            return;        }// fredt@users 20030813 - patch 1.7.2 - fix for column comparison within same table bugs #572075 and 722443        if (e1.getFilter() == this && e2.getFilter() == this) {            conditionType = CONDITION_UNORDERED;        } else if (e1.getFilter() == this) {            if (!e.isInJoin && isOuterJoin) {                // do not use a where condition on the second table in outer joins                return;            }

⌨️ 快捷键说明

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