Search in sources :

Example 1 with IndexLookupBatch

use of org.h2.index.IndexLookupBatch in project h2database by h2database.

the class TableFilter method getPlanSQL.

/**
 * Get the query execution plan text to use for this table filter.
 *
 * @param isJoin if this is a joined table
 * @return the SQL statement snippet
 */
public String getPlanSQL(boolean isJoin) {
    StringBuilder buff = new StringBuilder();
    if (isJoin) {
        if (joinOuter) {
            buff.append("LEFT OUTER JOIN ");
        } else {
            buff.append("INNER JOIN ");
        }
    }
    if (nestedJoin != null) {
        StringBuilder buffNested = new StringBuilder();
        TableFilter n = nestedJoin;
        do {
            buffNested.append(n.getPlanSQL(n != nestedJoin));
            buffNested.append('\n');
            n = n.getJoin();
        } while (n != null);
        String nested = buffNested.toString();
        boolean enclose = !nested.startsWith("(");
        if (enclose) {
            buff.append("(\n");
        }
        buff.append(StringUtils.indent(nested, 4, false));
        if (enclose) {
            buff.append(')');
        }
        if (isJoin) {
            buff.append(" ON ");
            if (joinCondition == null) {
                // need to have a ON expression,
                // otherwise the nesting is unclear
                buff.append("1=1");
            } else {
                buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
            }
        }
        return buff.toString();
    }
    if (table.isView() && ((TableView) table).isRecursive()) {
        buff.append(table.getName());
    } else {
        buff.append(table.getSQL());
    }
    if (table.isView() && ((TableView) table).isInvalid()) {
        throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, table.getName(), "not compiled");
    }
    if (alias != null) {
        buff.append(' ').append(Parser.quoteIdentifier(alias));
    }
    if (indexHints != null) {
        buff.append(" USE INDEX (");
        boolean first = true;
        for (String index : indexHints.getAllowedIndexes()) {
            if (!first) {
                buff.append(", ");
            } else {
                first = false;
            }
            buff.append(Parser.quoteIdentifier(index));
        }
        buff.append(")");
    }
    if (index != null) {
        buff.append('\n');
        StatementBuilder planBuff = new StatementBuilder();
        if (joinBatch != null) {
            IndexLookupBatch lookupBatch = joinBatch.getLookupBatch(joinFilterId);
            if (lookupBatch == null) {
                if (joinFilterId != 0) {
                    throw DbException.throwInternalError("" + joinFilterId);
                }
            } else {
                planBuff.append("batched:");
                String batchPlan = lookupBatch.getPlanSQL();
                planBuff.append(batchPlan);
                planBuff.append(" ");
            }
        }
        planBuff.append(index.getPlanSQL());
        if (!indexConditions.isEmpty()) {
            planBuff.append(": ");
            for (IndexCondition condition : indexConditions) {
                planBuff.appendExceptFirst("\n    AND ");
                planBuff.append(condition.getSQL());
            }
        }
        String plan = StringUtils.quoteRemarkSQL(planBuff.toString());
        if (plan.indexOf('\n') >= 0) {
            plan += "\n";
        }
        buff.append(StringUtils.indent("/* " + plan + " */", 4, false));
    }
    if (isJoin) {
        buff.append("\n    ON ");
        if (joinCondition == null) {
            // need to have a ON expression, otherwise the nesting is
            // unclear
            buff.append("1=1");
        } else {
            buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
        }
    }
    if (filterCondition != null) {
        buff.append('\n');
        String condition = StringUtils.unEnclose(filterCondition.getSQL());
        condition = "/* WHERE " + StringUtils.quoteRemarkSQL(condition) + "\n*/";
        buff.append(StringUtils.indent(condition, 4, false));
    }
    if (scanCount > 0) {
        buff.append("\n    /* scanCount: ").append(scanCount).append(" */");
    }
    return buff.toString();
}
Also used : IndexLookupBatch(org.h2.index.IndexLookupBatch) StatementBuilder(org.h2.util.StatementBuilder) IndexCondition(org.h2.index.IndexCondition)

Example 2 with IndexLookupBatch

use of org.h2.index.IndexLookupBatch in project h2database by h2database.

the class TableFilter method prepareJoinBatch.

/**
 * Attempt to initialize batched join.
 *
 * @param jb join batch if it is already created
 * @param filters the table filters
 * @param filter the filter index (0, 1,...)
 * @return join batch if query runs over index which supports batched
 *         lookups, {@code null} otherwise
 */
public JoinBatch prepareJoinBatch(JoinBatch jb, TableFilter[] filters, int filter) {
    assert filters[filter] == this;
    joinBatch = null;
    joinFilterId = -1;
    if (getTable().isView()) {
        session.pushSubQueryInfo(masks, filters, filter, select.getSortOrder());
        try {
            ((ViewIndex) index).getQuery().prepareJoinBatch();
        } finally {
            session.popSubQueryInfo();
        }
    }
    // For globally top table filter we don't need to create lookup batch,
    // because currently it will not be used (this will be shown in
    // ViewIndex.getPlanSQL()). Probably later on it will make sense to
    // create it to better support X IN (...) conditions, but this needs to
    // be implemented separately. If isAlwaysTopTableFilter is false then we
    // either not a top table filter or top table filter in a sub-query,
    // which in turn is not top in outer query, thus we need to enable
    // batching here to allow outer query run batched join against this
    // sub-query.
    IndexLookupBatch lookupBatch = null;
    if (jb == null && select != null && !isAlwaysTopTableFilter(filter)) {
        lookupBatch = index.createLookupBatch(filters, filter);
        if (lookupBatch != null) {
            jb = new JoinBatch(filter + 1, join);
        }
    }
    if (jb != null) {
        if (nestedJoin != null) {
            throw DbException.throwInternalError();
        }
        joinBatch = jb;
        joinFilterId = filter;
        if (lookupBatch == null && !isAlwaysTopTableFilter(filter)) {
            // createLookupBatch will be called at most once because jb can
            // be created only if lookupBatch is already not null from the
            // call above.
            lookupBatch = index.createLookupBatch(filters, filter);
            if (lookupBatch == null) {
                // the index does not support lookup batching, need to fake
                // it because we are not top
                lookupBatch = JoinBatch.createFakeIndexLookupBatch(this);
            }
        }
        jb.register(this, lookupBatch);
    }
    return jb;
}
Also used : IndexLookupBatch(org.h2.index.IndexLookupBatch)

Example 3 with IndexLookupBatch

use of org.h2.index.IndexLookupBatch in project h2database by h2database.

the class JoinBatch method createViewIndexLookupBatch.

/**
 * Create index lookup batch for a view index.
 *
 * @param viewIndex view index
 * @return index lookup batch or {@code null} if batching is not supported
 *         for this query
 */
public static IndexLookupBatch createViewIndexLookupBatch(ViewIndex viewIndex) {
    Query query = viewIndex.getQuery();
    if (query.isUnion()) {
        ViewIndexLookupBatchUnion unionBatch = new ViewIndexLookupBatchUnion(viewIndex);
        return unionBatch.initialize() ? unionBatch : null;
    }
    JoinBatch jb = ((Select) query).getJoinBatch();
    if (jb == null || jb.getLookupBatch(0) == null) {
        // our sub-query is not batched or is top batched sub-query
        return null;
    }
    assert !jb.batchedSubQuery;
    jb.batchedSubQuery = true;
    return jb.viewIndexLookupBatch(viewIndex);
}
Also used : Query(org.h2.command.dml.Query) Select(org.h2.command.dml.Select)

Example 4 with IndexLookupBatch

use of org.h2.index.IndexLookupBatch in project ignite by apache.

the class GridH2ProxyIndex method createLookupBatch.

/**
 * {@inheritDoc}
 */
@Override
public IndexLookupBatch createLookupBatch(TableFilter[] filters, int filter) {
    IndexLookupBatch batch = idx.createLookupBatch(filters, filter);
    if (batch == null)
        return null;
    GridH2RowDescriptor rowDesc = ((GridH2Table) idx.getTable()).rowDescriptor();
    return new ProxyDistributedLookupBatch(batch, rowDesc);
}
Also used : ProxyDistributedLookupBatch(org.apache.ignite.internal.processors.query.h2.opt.join.ProxyDistributedLookupBatch) IndexLookupBatch(org.h2.index.IndexLookupBatch)

Example 5 with IndexLookupBatch

use of org.h2.index.IndexLookupBatch in project ignite by apache.

the class GridH2IndexBase method createLookupBatch.

/**
 * {@inheritDoc}
 */
@Override
public IndexLookupBatch createLookupBatch(TableFilter[] filters, int filter) {
    GridH2QueryContext qctx = GridH2QueryContext.get();
    if (qctx == null || qctx.distributedJoinMode() == OFF || !getTable().isPartitioned())
        return null;
    IndexColumn affCol = getTable().getAffinityKeyColumn();
    GridH2RowDescriptor desc = getTable().rowDescriptor();
    int affColId = -1;
    boolean ucast = false;
    if (affCol != null) {
        affColId = affCol.column.getColumnId();
        int[] masks = filters[filter].getMasks();
        if (masks != null) {
            ucast = (masks[affColId] & IndexCondition.EQUALITY) != 0 || desc.checkKeyIndexCondition(masks, IndexCondition.EQUALITY);
        }
    }
    GridCacheContext<?, ?> cctx = getTable().rowDescriptor().context();
    return new DistributedLookupBatch(cctx, ucast, affColId);
}
Also used : IndexColumn(org.h2.table.IndexColumn)

Aggregations

IndexLookupBatch (org.h2.index.IndexLookupBatch)3 IndexColumn (org.h2.table.IndexColumn)2 IndexQueryContext (org.apache.ignite.internal.cache.query.index.sorted.inline.IndexQueryContext)1 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)1 QueryContext (org.apache.ignite.internal.processors.query.h2.opt.QueryContext)1 DistributedLookupBatch (org.apache.ignite.internal.processors.query.h2.opt.join.DistributedLookupBatch)1 ProxyDistributedLookupBatch (org.apache.ignite.internal.processors.query.h2.opt.join.ProxyDistributedLookupBatch)1 Query (org.h2.command.dml.Query)1 Select (org.h2.command.dml.Select)1 IndexCondition (org.h2.index.IndexCondition)1 StatementBuilder (org.h2.util.StatementBuilder)1