001: /* Copyright (c) 2001-2005, The HSQL Development Group
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the HSQL Development Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package org.hsqldb;
032:
033: import org.hsqldb.lib.ObjectComparator;
034:
035: /**
036: * Represents an SQL view or anonymous subquery (inline virtual table
037: * descriptor) nested within an SQL statement. <p>
038: *
039: * Implements {@link org.hsqldb.lib.ObjectComparator ObjectComparator} to
040: * provide the correct order of materialization for nested views / subqueries.
041: *
042: * @author boucherb@users
043: * @author fredt@users
044: */
045: class SubQuery implements ObjectComparator {
046:
047: int level;
048: boolean hasParams;
049: boolean isResolved;
050: boolean isExistsPredicate;
051: boolean uniqueRows;
052: Select select;
053: Table table;
054: View view;
055: boolean isMaterialised;
056:
057: void populateTable(Session session) throws HsqlException {
058:
059: Result r = select.getResult(session, isExistsPredicate ? 1 : 0);
060:
061: if (uniqueRows) {
062: r.removeDuplicates(session, select.iResultLen);
063: }
064:
065: table.insertResult(session, r);
066: }
067:
068: /**
069: * This results in the following sort order:
070: *
071: * view subqueries, then other subqueries
072: *
073: * view subqueries:
074: * views sorted by creation order (earlier declaration first)
075: *
076: * other subqueries:
077: * subqueries sorted by depth within select query (deep == higher level)
078: *
079: */
080: public int compare(Object a, Object b) {
081:
082: SubQuery sqa = (SubQuery) a;
083: SubQuery sqb = (SubQuery) b;
084:
085: if (sqa.view == null && sqb.view == null) {
086: return sqb.level - sqa.level;
087: } else if (sqa.view != null && sqb.view != null) {
088: Database db = sqa.view.database;
089: int ia = db.schemaManager.getTableIndex(sqa.view);
090: int ib = db.schemaManager.getTableIndex(sqb.view);
091:
092: if (ia == -1) {
093: ia = db.schemaManager.getTables(
094: sqa.view.getSchemaName()).size();
095: }
096:
097: if (ib == -1) {
098: ib = db.schemaManager.getTables(
099: sqb.view.getSchemaName()).size();
100: }
101:
102: int diff = ia - ib;
103:
104: return diff == 0 ? sqb.level - sqa.level : diff;
105: } else {
106: return sqa.view == null ? 1 : -1;
107: }
108: }
109: }
|