Search in sources :

Example 1 with H2TreeIndexBase

use of org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase in project ignite by apache.

the class ValidateIndexesClosure method processPartIterator.

/**
 * Process partition iterator.
 *
 * @param grpCtx Cache group context.
 * @param partRes Result object.
 * @param session H2 session.
 * @param it Partition iterator.
 * @throws IgniteCheckedException
 */
private void processPartIterator(CacheGroupContext grpCtx, ValidateIndexesPartitionResult partRes, Session session, GridIterator<CacheDataRow> it) throws IgniteCheckedException {
    boolean enoughIssues = false;
    GridQueryProcessor qryProcessor = ignite.context().query();
    final boolean skipConditions = checkFirst > 0 || checkThrough > 0;
    final boolean bothSkipConditions = checkFirst > 0 && checkThrough > 0;
    long current = 0;
    long processedNumber = 0;
    while (it.hasNextX() && !validateCtx.isCancelled()) {
        if (enoughIssues)
            break;
        CacheDataRow row = it.nextX();
        if (skipConditions) {
            if (bothSkipConditions) {
                if (processedNumber > checkFirst)
                    break;
                else if (current++ % checkThrough > 0)
                    continue;
                else
                    processedNumber++;
            } else {
                if (checkFirst > 0) {
                    if (current++ > checkFirst)
                        break;
                } else {
                    if (current++ % checkThrough > 0)
                        continue;
                }
            }
        }
        int cacheId = row.cacheId() == 0 ? grpCtx.groupId() : row.cacheId();
        GridCacheContext<?, ?> cacheCtx = row.cacheId() == 0 ? grpCtx.singleCacheContext() : grpCtx.shared().cacheContext(row.cacheId());
        if (cacheCtx == null)
            throw new IgniteException("Unknown cacheId of CacheDataRow: " + cacheId);
        if (row.link() == 0L) {
            String errMsg = "Invalid partition row, possibly deleted";
            log.error(errMsg);
            IndexValidationIssue is = new IndexValidationIssue(null, cacheCtx.name(), null, new IgniteCheckedException(errMsg));
            enoughIssues |= partRes.reportIssue(is);
            continue;
        }
        QueryTypeDescriptorImpl res = qryProcessor.typeByValue(cacheCtx.name(), cacheCtx.cacheObjectContext(), row.key(), row.value(), true);
        if (res == null)
            // Tolerate - (k, v) is just not indexed.
            continue;
        IgniteH2Indexing indexing = (IgniteH2Indexing) qryProcessor.getIndexing();
        GridH2Table gridH2Tbl = indexing.schemaManager().dataTable(cacheCtx.name(), res.tableName());
        if (gridH2Tbl == null)
            // Tolerate - (k, v) is just not indexed.
            continue;
        GridH2RowDescriptor gridH2RowDesc = gridH2Tbl.rowDescriptor();
        H2CacheRow h2Row = gridH2RowDesc.createRow(row);
        ArrayList<Index> indexes = gridH2Tbl.getIndexes();
        for (Index idx : indexes) {
            if (validateCtx.isCancelled())
                break;
            if (!(idx instanceof H2TreeIndexBase))
                continue;
            try {
                Cursor cursor = idx.find(session, h2Row, h2Row);
                if (cursor == null || !cursor.next())
                    throw new IgniteCheckedException("Key is present in CacheDataTree, but can't be found in SQL index.");
            } catch (Throwable t) {
                Object o = CacheObjectUtils.unwrapBinaryIfNeeded(grpCtx.cacheObjectContext(), row.key(), true, true);
                IndexValidationIssue is = new IndexValidationIssue(o.toString(), cacheCtx.name(), idx.getName(), t);
                log.error("Failed to lookup key: " + is.toString(), t);
                enoughIssues |= partRes.reportIssue(is);
            }
        }
    }
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) QueryTypeDescriptorImpl(org.apache.ignite.internal.processors.query.QueryTypeDescriptorImpl) H2TreeIndexBase(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase) Index(org.h2.index.Index) H2CacheRow(org.apache.ignite.internal.processors.query.h2.opt.H2CacheRow) Cursor(org.h2.index.Cursor) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) IgniteException(org.apache.ignite.IgniteException) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridQueryProcessor(org.apache.ignite.internal.processors.query.GridQueryProcessor) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) IgniteH2Indexing(org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing)

Example 2 with H2TreeIndexBase

use of org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase in project ignite by apache.

the class H2TableDescriptor method createSystemIndexes.

/**
 * Create list of indexes. First must be primary key, after that all unique indexes and only then non-unique
 * indexes. All indexes must be subtypes of {@link H2TreeIndexBase}.
 *
 * @param tbl Table to create indexes for.
 * @return List of indexes.
 */
public ArrayList<Index> createSystemIndexes(GridH2Table tbl) {
    ArrayList<Index> idxs = new ArrayList<>();
    IndexColumn keyCol = tbl.indexColumn(QueryUtils.KEY_COL, SortOrder.ASCENDING);
    IndexColumn affCol = tbl.getAffinityKeyColumn();
    if (affCol != null && H2Utils.equals(affCol, keyCol))
        affCol = null;
    List<IndexColumn> unwrappedKeyAndAffinityCols = extractKeyColumns(tbl, keyCol, affCol);
    List<IndexColumn> wrappedKeyCols = H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), keyCol, affCol);
    Index hashIdx = createHashIndex(tbl, wrappedKeyCols);
    if (hashIdx != null)
        idxs.add(hashIdx);
    // Add primary key index.
    Index pkIdx = idx.createSortedIndex(PK_IDX_NAME, tbl, true, false, unwrappedKeyAndAffinityCols, wrappedKeyCols, tbl.rowDescriptor().tableDescriptor().type().primaryKeyInlineSize(), null);
    idxs.add(pkIdx);
    if (type().valueClass() == String.class && !idx.distributedConfiguration().isDisableCreateLuceneIndexForStringValueType()) {
        try {
            luceneIdx = new GridLuceneIndex(idx.kernalContext(), tbl.cacheName(), type);
        } catch (IgniteCheckedException e1) {
            throw new IgniteException(e1);
        }
    }
    GridQueryIndexDescriptor textIdx = type.textIndex();
    if (textIdx != null) {
        try {
            luceneIdx = new GridLuceneIndex(idx.kernalContext(), tbl.cacheName(), type);
        } catch (IgniteCheckedException e1) {
            throw new IgniteException(e1);
        }
    }
    // Locate index where affinity column is first (if any).
    if (affCol != null) {
        boolean affIdxFound = false;
        for (GridQueryIndexDescriptor idxDesc : type.indexes().values()) {
            if (idxDesc.type() != QueryIndexType.SORTED)
                continue;
            String firstField = idxDesc.fields().iterator().next();
            Column col = tbl.getColumn(firstField);
            IndexColumn idxCol = tbl.indexColumn(col.getColumnId(), idxDesc.descending(firstField) ? SortOrder.DESCENDING : SortOrder.ASCENDING);
            affIdxFound |= H2Utils.equals(idxCol, affCol);
        }
        // Add explicit affinity key index if nothing alike was found.
        if (!affIdxFound) {
            List<IndexColumn> unwrappedKeyCols = extractKeyColumns(tbl, keyCol, null);
            ArrayList<IndexColumn> colsWithUnwrappedKey = new ArrayList<>(unwrappedKeyCols.size());
            colsWithUnwrappedKey.add(affCol);
            // We need to reorder PK columns to have affinity key as first column, that's why we can't use simple PK columns
            H2Utils.addUniqueColumns(colsWithUnwrappedKey, unwrappedKeyCols);
            List<IndexColumn> cols = H2Utils.treeIndexColumns(tbl.rowDescriptor(), new ArrayList<>(2), affCol, keyCol);
            idxs.add(idx.createSortedIndex(AFFINITY_KEY_IDX_NAME, tbl, false, true, colsWithUnwrappedKey, cols, tbl.rowDescriptor().tableDescriptor().type().affinityFieldInlineSize(), null));
        }
    }
    return idxs;
}
Also used : ArrayList(java.util.ArrayList) GridLuceneIndex(org.apache.ignite.internal.processors.query.h2.opt.GridLuceneIndex) GridLuceneIndex(org.apache.ignite.internal.processors.query.h2.opt.GridLuceneIndex) Index(org.h2.index.Index) H2PkHashIndex(org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex) IndexColumn(org.h2.table.IndexColumn) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Column(org.h2.table.Column) IndexColumn(org.h2.table.IndexColumn) IgniteException(org.apache.ignite.IgniteException) GridQueryIndexDescriptor(org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor)

Example 3 with H2TreeIndexBase

use of org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase in project ignite by apache.

the class GridCommandHandlerBrokenIndexTest method addBadIndex.

/**
 * Adds index that fails on {@code find()}.
 */
private void addBadIndex() {
    IgniteEx ignite = grid(0);
    int grpId = CU.cacheGroupId(CACHE_NAME, GROUP_NAME);
    CacheGroupContext grpCtx = ignite.context().cache().cacheGroup(grpId);
    assertNotNull(grpCtx);
    GridQueryProcessor qry = ignite.context().query();
    IgniteH2Indexing indexing = (IgniteH2Indexing) qry.getIndexing();
    outer: for (GridCacheContext ctx : grpCtx.caches()) {
        Collection<GridQueryTypeDescriptor> types = qry.types(ctx.name());
        if (!F.isEmpty(types)) {
            for (GridQueryTypeDescriptor type : types) {
                GridH2Table gridH2Tbl = indexing.schemaManager().dataTable(ctx.name(), type.tableName());
                if (gridH2Tbl == null)
                    continue;
                ArrayList<Index> indexes = gridH2Tbl.getIndexes();
                BadIndex bi = null;
                for (Index idx : indexes) {
                    if (idx instanceof H2TreeIndexBase) {
                        bi = new BadIndex(gridH2Tbl, IDX_NAME, idx.getIndexColumns(), idx.getIndexType());
                        break;
                    }
                }
                if (bi != null) {
                    indexes.add(bi);
                    break outer;
                }
            }
        }
    }
}
Also used : GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) H2TreeIndexBase(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase) ArrayList(java.util.ArrayList) Index(org.h2.index.Index) GridQueryTypeDescriptor(org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor) IgniteEx(org.apache.ignite.internal.IgniteEx) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridQueryProcessor(org.apache.ignite.internal.processors.query.GridQueryProcessor) Collection(java.util.Collection) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) IgniteH2Indexing(org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing)

Example 4 with H2TreeIndexBase

use of org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase in project ignite by apache.

the class GridH2Table method indexesInformation.

/**
 * @return Information about all indexes related to the table.
 */
@SuppressWarnings("ZeroLengthArrayAllocation")
public List<IndexInformation> indexesInformation() {
    List<IndexInformation> res = new ArrayList<>();
    IndexColumn keyCol = indexColumn(QueryUtils.KEY_COL, SortOrder.ASCENDING);
    List<IndexColumn> wrappedKeyCols = H2Utils.treeIndexColumns(rowDescriptor(), new ArrayList<>(2), keyCol, affKeyCol);
    // explicit add HASH index, due to we know all their parameters and it doesn't created on non afinity nodes.
    res.add(new IndexInformation(false, true, PK_HASH_IDX_NAME, H2IndexType.HASH, H2Utils.indexColumnsSql(H2Utils.unwrapKeyColumns(this, wrappedKeyCols.toArray(new IndexColumn[0]))), null));
    // explicit add SCAN index, due to we know all their parameters and it depends on affinity node or not.
    res.add(new IndexInformation(false, false, SCAN_INDEX_NAME_SUFFIX, H2IndexType.SCAN, null, null));
    for (Index idx : idxs) {
        if (idx instanceof H2TreeIndexBase) {
            res.add(new IndexInformation(idx.getIndexType().isPrimaryKey(), idx.getIndexType().isUnique(), idx.getName(), H2IndexType.BTREE, H2Utils.indexColumnsSql(H2Utils.unwrapKeyColumns(this, idx.getIndexColumns())), ((H2TreeIndexBase) idx).inlineSize()));
        } else if (idx.getIndexType().isSpatial()) {
            res.add(new IndexInformation(false, false, idx.getName(), H2IndexType.SPATIAL, H2Utils.indexColumnsSql(idx.getIndexColumns()), null));
        }
    }
    return res;
}
Also used : IndexInformation(org.apache.ignite.internal.processors.query.h2.database.IndexInformation) H2TreeIndexBase(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase) ArrayList(java.util.ArrayList) Index(org.h2.index.Index) H2TreeIndex(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex) SpatialIndex(org.h2.index.SpatialIndex) IndexColumn(org.h2.table.IndexColumn)

Example 5 with H2TreeIndexBase

use of org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase in project ignite by apache.

the class GridH2Table method createDuplicateIndexIfNeeded.

/**
 * Creates proxy index for given target index.
 * Proxy index refers to alternative key and val columns.
 *
 * @param target Index to clone.
 * @return Proxy index.
 */
private Index createDuplicateIndexIfNeeded(Index target) {
    if (!(target instanceof H2TreeIndexBase) && !(target instanceof SpatialIndex))
        return null;
    IndexColumn[] cols = target.getIndexColumns();
    List<IndexColumn> proxyCols = new ArrayList<>(cols.length);
    boolean modified = false;
    for (IndexColumn col : cols) {
        IndexColumn proxyCol = new IndexColumn();
        proxyCol.columnName = col.columnName;
        proxyCol.column = col.column;
        proxyCol.sortType = col.sortType;
        int altColId = desc.getAlternativeColumnId(proxyCol.column.getColumnId());
        if (altColId != proxyCol.column.getColumnId()) {
            proxyCol.column = getColumn(altColId);
            proxyCol.columnName = proxyCol.column.getName();
            modified = true;
        }
        proxyCols.add(proxyCol);
    }
    if (modified) {
        String proxyName = target.getName() + "_proxy";
        if (target.getIndexType().isSpatial())
            return new GridH2ProxySpatialIndex(this, proxyName, proxyCols, target);
        return new GridH2ProxyIndex(this, proxyName, proxyCols, target);
    }
    return null;
}
Also used : H2TreeIndexBase(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase) SpatialIndex(org.h2.index.SpatialIndex) ArrayList(java.util.ArrayList) IndexColumn(org.h2.table.IndexColumn)

Aggregations

ArrayList (java.util.ArrayList)5 H2TreeIndexBase (org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase)5 Index (org.h2.index.Index)5 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)3 IgniteException (org.apache.ignite.IgniteException)3 GridQueryProcessor (org.apache.ignite.internal.processors.query.GridQueryProcessor)3 IgniteH2Indexing (org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing)3 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)3 IndexColumn (org.h2.table.IndexColumn)3 Collection (java.util.Collection)2 IgniteEx (org.apache.ignite.internal.IgniteEx)2 CacheGroupContext (org.apache.ignite.internal.processors.cache.CacheGroupContext)2 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)2 GridQueryTypeDescriptor (org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor)2 SpatialIndex (org.h2.index.SpatialIndex)2 Collections (java.util.Collections)1 Collections.emptyMap (java.util.Collections.emptyMap)1 Collections.newSetFromMap (java.util.Collections.newSetFromMap)1 Collections.shuffle (java.util.Collections.shuffle)1 HashMap (java.util.HashMap)1