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);
}
}
}
}
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;
}
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;
}
}
}
}
}
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;
}
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;
}
Aggregations