`

hsqldb源码分析系列4 查询引擎之查询操作

 
阅读更多

 

   查询过程前面解析类似insert,最终调用是在下面这个QuerySpecification类的getSingleResult方法,RangeVariable是查询条件相关

   

  private Result getSingleResult(Session session, int maxRows) {

        int[] limits = sortAndSlice.getLimits(session, this, maxRows);
        Result              r         = buildResult(session, limits);
        RowSetNavigatorData navigator = (RowSetNavigatorData) r.getNavigator();

        if (isDistinctSelect) {
            navigator.removeDuplicates(session);
        }

        if (sortAndSlice.hasOrder()) {
            navigator.sortOrder(session);
        }

        if (limits != SortAndSlice.defaultLimits
                && !sortAndSlice.skipFullResult) {
            navigator.trim(limits[0], limits[1]);
        }

        return r;
    }

    private Result buildResult(Session session, int[] limits) {

        RowSetNavigatorData navigator = new RowSetNavigatorData(session,
            (QuerySpecification) this);
        Result result = Result.newResult(navigator);

        result.metaData = resultMetaData;

        if (isUpdatable) {
            result.rsProperties = ResultProperties.updatablePropsValue;
        }

        int skipCount  = 0;
        int limitCount = limits[2];

        if (sortAndSlice.skipFullResult) {
            skipCount  = limits[0];
            limitCount = limits[1];
        }

        if (this.isSimpleCount) {
            Object[] data  = new Object[indexLimitData];
            Table    table = rangeVariables[0].getTable();

            table.materialise(session);

            PersistentStore store = table.getRowStore(session);
            long            count = store.elementCount(session);

            data[0] = data[indexStartAggregates] = ValuePool.getLong(count);

            navigator.add(data);

            return result;
        }

        int fullJoinIndex = 0;
        RangeIterator[] rangeIterators =
            new RangeIterator[rangeVariables.length];

        for (int i = 0; i < rangeVariables.length; i++) {
            rangeIterators[i] = rangeVariables[i].getIterator(session);
        }

        session.sessionContext.rownum = 1;

        for (int currentIndex = 0; ; ) {
            if (currentIndex < fullJoinIndex) {

                // finished current span
                // or finished outer rows on right navigator
                boolean end = true;

                for (int i = fullJoinIndex + 1; i < rangeVariables.length;
                        i++) {
                    if (rangeVariables[i].isRightJoin) {
                        fullJoinIndex = i;
                        currentIndex  = i;
                        end           = false;

                        ((RangeIteratorRight) rangeIterators[i])
                            .setOnOuterRows();

                        break;
                    }
                }

                if (end) {
                    break;
                }
            }

            RangeIterator it = rangeIterators[currentIndex];

            if (it.next()) {
                if (currentIndex < rangeVariables.length - 1) {
                    currentIndex++;

                    continue;
                }
            } else {
                it.reset();

                currentIndex--;

                continue;
            }

            if (limitCount == 0) {
                break;
            }

            session.sessionData.startRowProcessing();

            Object[] data = new Object[indexLimitData];

            for (int i = 0; i < indexStartAggregates; i++) {
                if (isAggregated && aggregateCheck[i]) {
                    continue;
                } else {
                    data[i] = exprColumns[i].getValue(session);
                }
            }

            for (int i = indexLimitVisible; i < indexLimitRowId; i++) {
                if (i == indexLimitVisible) {
                    data[i] = it.getRowidObject();
                } else {
                    data[i] = it.getCurrentRow();
                }
            }

            session.sessionContext.rownum++;

            if (skipCount > 0) {
                skipCount--;

                continue;
            }

            Object[] groupData = null;

            if (isAggregated || isGrouped) {
                groupData = navigator.getGroupData(data);

                if (groupData != null) {
                    data = groupData;
                }
            }

            for (int i = indexStartAggregates; i < indexLimitExpressions;
                    i++) {
                data[i] = exprColumns[i].updateAggregatingValue(session,
                        data[i]);
            }

            if (groupData == null) {
                navigator.add(data);
            } else if (isAggregated) {
                navigator.update(groupData, data);
            }

            int rowCount = navigator.getSize();

            if (rowCount == session.resultMaxMemoryRows && !isAggregated
                    && !isSingleMemoryTable) {
                navigator = new RowSetNavigatorDataTable(session, this,
                        navigator);

                result.setNavigator(navigator);
            }

            if (isAggregated || isGrouped) {
                if (!sortAndSlice.isGenerated) {
                    continue;
                }
            }

            if (rowCount >= limitCount) {
                break;
            }
        }

        navigator.reset();

        for (int i = 0; i < rangeVariables.length; i++) {
            rangeIterators[i].reset();
        }

        if (!isGrouped && !isAggregated) {
            return result;
        }

        if (isAggregated) {
            if (!isGrouped && navigator.getSize() == 0) {
                Object[] data = new Object[exprColumns.length];

                for (int i = 0; i < indexStartAggregates; i++) {
                    if (!aggregateCheck[i]) {
                        data[i] = exprColumns[i].getValue(session);
                    }
                }

                navigator.add(data);
            }

            navigator.reset();
            session.sessionContext.setRangeIterator(navigator);

            while (navigator.next()) {
                Object[] data = navigator.getCurrent();

                for (int i = indexStartAggregates; i < indexLimitExpressions;
                        i++) {
                    data[i] = exprColumns[i].getAggregatedValue(session,
                            data[i]);
                }

                for (int i = 0; i < indexStartAggregates; i++) {
                    if (aggregateCheck[i]) {
                        data[i] = exprColumns[i].getValue(session);
                    }
                }
            }

            session.sessionContext.unsetRangeIterator(navigator);
        }

        navigator.reset();

        if (havingCondition != null) {
            while (navigator.hasNext()) {
                Object[] data = (Object[]) navigator.getNext();

                if (!Boolean.TRUE.equals(
                        data[indexLimitVisible + groupByColumnCount])) {
                    navigator.remove();
                }
            }

            navigator.reset();
        }

        return result;
    }

 

     比如一个like操作,

       

 



 

查询结果:

   

 

这个StatementQuery实在复杂,再慢慢搞懂吧



 

  • 大小: 221.6 KB
  • 大小: 193.8 KB
  • 大小: 212.2 KB
  • 大小: 127.5 KB
分享到:
评论

相关推荐

    HSQLDB

    由于HSQLDB是开源的,开发者可以深入研究其源码,理解数据库的内部工作原理,如查询解析、执行计划生成、事务管理等,这对提升数据库相关的技术能力非常有帮助。 总之,HSQLDB作为一个轻量级、高性能的数据库,广泛...

    Hsqldb的缓存分析及调试步骤

    HSQLDB(HyperSQL Database)是一个轻量级、高性能的关系型数据库引擎,常用于Java应用程序和测试环境中。它的缓存机制和数据存储方式对于理解其性能和操作至关重要。以下是对HSQLDB的缓存分析和调试步骤的详细解释...

    hsqldb使用(转载)

    HSQldb是一个轻量级的关系型...HSQldb的灵活性和易用性使其成为开发人员的首选数据库之一,特别是在快速迭代和测试环境中。其强大的特性,如内存数据库、自动创建数据库以及内置的管理工具,都极大地简化了数据库管理。

    开源数据库软件hsqldb

    3. **高性能**:HSQldb在处理大量数据时表现出良好的性能,得益于其高效的查询引擎和内存管理机制。 4. **支持SQL标准**:HSQldb兼容大部分SQL92和SQL99标准,提供丰富的SQL语句支持。 5. **嵌入式数据库**:...

    HSQLDB的使用

    **源码分析** HSQLDB是用Java编写的,因此其源码可读性较高,对于学习数据库原理和实现有很高的价值。通过阅读源码,开发者可以深入理解SQL的执行流程、事务管理、索引构建等核心概念。 **工具支持** HSQLDB提供...

    HSQLDB 1.8.0

    《HSQLDB 1.8.0:轻量级数据库引擎的深度剖析》 HSQLDB,全称为HyperSQL Database,是一款开源、轻量级、高性能的关系型数据库管理系统,广泛应用于嵌入式系统和测试环境。HSQLDB 1.8.0是该数据库引擎的一个重要...

    hsqldb-2.3.4

    4. **强大的查询能力**:HSQldb支持复杂的SQL查询,包括子查询、联接操作、视图等。 5. **自动备份与恢复**:HSQldb 2.3.4支持定时自动备份,确保数据安全。 6. **嵌入式与独立服务器模式**:HSQldb可以作为Java应用...

    HSQLDB中文帮助文档

    ### HSQLDB中文帮助文档知识点...综上所述,HSQLDB作为一款功能强大的轻量级数据库管理系统,在许多方面都表现出了优秀的能力,不仅支持标准SQL语法,还具备良好的跨平台特性,是开发和部署Java应用的理想选择之一。

    HSQLDB快速连接数据库

    - **约束和索引**:详细阐述了如何在HSQLDB中定义和使用主键、唯一性约束、唯一性索引以及外键约束,并分析了这些约束和索引如何影响查询性能。 - **类型和算术操作**:介绍了HSQLDB支持的各种数据类型,包括整型、...

    hsqldb管理工具

    HSQldb客户端是HSQldb的重要组成部分,它提供了一系列工具,包括命令行接口和图形用户界面,用于创建、查询、更新和管理数据库。这些工具使得开发者和数据库管理员可以进行数据的导入导出、备份恢复、性能监控等操作...

    hsqldb实例源代码

    总结来说,HSQldb实例源代码为我们提供了学习和实践HSQldb数据库操作的实例,涵盖了数据库的创建、数据操作以及查询等核心功能。通过研究这些代码,开发者可以快速掌握HSQldb的使用,并将其应用于自己的项目中,无论...

    <转>HSQLDB 安装与使用

    HSQLDB的性能可以通过调整内存大小、使用存储引擎类型(内存或文件)、索引策略等方式进行优化。在处理大量数据时,合理设计表结构和索引能显著提升查询效率。 总之,HSQLDB是一款强大且灵活的数据库解决方案,无论...

    hsqldb的最新版本

    4. **API更新**:HSQldb提供了Java API供开发者进行数据库操作,1.9.0版本可能更新了API,增加了新的方法或改进了原有方法,以提高开发效率。 5. **稳定性与兼容性**:新版本通常会修复已知的bug,确保与其他软件的...

    HSQLDB中文手册

    HSQLDB提供了一系列实用工具,如DatabaseManager、TransferTool、QueryTool和SqlTool,分别用于图形界面管理、数据迁移、查询执行和命令行操作,大大简化了数据库的日常管理和维护工作。 #### 七、版权与翻译声明 ...

    HSQLDB_guide

    这两本书籍详尽地介绍了HSQLDB的安装、配置、使用方法以及高级特性,包括数据库创建、表操作、查询语言、事务处理、备份与恢复等内容,是学习和掌握HSQLDB的重要资料。 通过阅读这两份指南,你可以了解到如何创建...

    hsqldb 2.25

    在本压缩包中,提供的HSQldb版本为2.25,特别之处在于它是针对JDK 1.5编译的。由于HSQldb自2.0版本起,官方默认使用JDK 1.6或更高版本进行编译,这可能对仍在使用JDK 1.5的开发者造成兼容性问题。因此,HSQldb 2.25...

    hsqldb-2.3.3.zip

    4. **操作数据库**:使用SQL语句进行数据表创建、数据插入、查询等操作。 5. **关闭数据库**:通过命令关闭数据库服务器,释放资源。 四、HSQldb 2.3.3的应用场景 1. **开发测试**:在开发过程中,HSQldb作为临时...

    hsqldb-2.2.8数据库

    HSQldb的一大特点是支持标准SQL语法,这使得开发人员可以使用熟悉的SQL命令进行数据操作,而无需学习新的查询语言。同时,HSQldb提供了丰富的JAVA接口,包括JDBC驱动程序,使得开发者能够轻松地在Java应用程序中集成...

Global site tag (gtag.js) - Google Analytics