use of org.h2.index.Index in project ignite by apache.
the class IgniteH2Indexing method rebuildIndexesFromHash.
/** {@inheritDoc} */
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
@Override
public void rebuildIndexesFromHash(GridCacheContext cctx, String schemaName, String typeName) throws IgniteCheckedException {
H2TableDescriptor tbl = tableDescriptor(schemaName, typeName);
if (tbl == null)
return;
assert tbl.table() != null;
assert tbl.table().rebuildFromHashInProgress();
H2PkHashIndex hashIdx = tbl.primaryKeyHashIndex();
Cursor cursor = hashIdx.find((Session) null, null, null);
while (cursor.next()) {
CacheDataRow dataRow = (CacheDataRow) cursor.get();
boolean done = false;
while (!done) {
GridCacheEntryEx entry = cctx.cache().entryEx(dataRow.key());
try {
synchronized (entry) {
// TODO : How to correctly get current value and link here?
GridH2Row row = tbl.table().rowDescriptor().createRow(entry.key(), entry.partition(), dataRow.value(), entry.version(), entry.expireTime());
row.link(dataRow.link());
List<Index> indexes = tbl.table().getAllIndexes();
for (int i = 2; i < indexes.size(); i++) {
Index idx = indexes.get(i);
if (idx instanceof H2TreeIndex)
((H2TreeIndex) idx).put(row);
}
done = true;
}
} catch (GridCacheEntryRemovedException e) {
// No-op
}
}
}
tbl.table().markRebuildFromHashInProgress(false);
}
use of org.h2.index.Index in project ignite by apache.
the class GridH2TableSelfTest method checkIndexesConsistent.
/**
* @param idxs Indexes.
* @param rowSet Rows.
* @return Rows.
*/
private Set<Row> checkIndexesConsistent(ArrayList<Index> idxs, @Nullable Set<Row> rowSet) throws IgniteCheckedException {
for (Index idx : idxs) {
if (!(idx instanceof GridH2TreeIndex))
continue;
Set<Row> set = new HashSet<>();
GridCursor<GridH2Row> cursor = ((GridH2TreeIndex) idx).rows();
while (cursor.next()) assertTrue(set.add(cursor.get()));
if (rowSet == null || rowSet.isEmpty())
rowSet = set;
else
assertEquals(rowSet, set);
}
return rowSet;
}
use of org.h2.index.Index in project ignite by apache.
the class GridMapQueryExecutor method onQueryRequest0.
/**
* @param node Node authored request.
* @param reqId Request ID.
* @param segmentId index segment ID.
* @param schemaName Schema name.
* @param qrys Queries to execute.
* @param cacheIds Caches which will be affected by these queries.
* @param topVer Topology version.
* @param partsMap Partitions map for unstable topology.
* @param parts Explicit partitions for current node.
* @param tbls Tables.
* @param pageSize Page size.
* @param distributedJoinMode Query distributed join mode.
*/
private void onQueryRequest0(ClusterNode node, long reqId, int segmentId, String schemaName, Collection<GridCacheSqlQuery> qrys, List<Integer> cacheIds, AffinityTopologyVersion topVer, Map<UUID, int[]> partsMap, int[] parts, Collection<QueryTable> tbls, int pageSize, DistributedJoinMode distributedJoinMode, boolean enforceJoinOrder, boolean replicated, int timeout, Object[] params) {
// Prepare to run queries.
GridCacheContext<?, ?> mainCctx = !F.isEmpty(cacheIds) ? ctx.cache().context().cacheContext(cacheIds.get(0)) : null;
NodeResults nodeRess = resultsForNode(node.id());
QueryResults qr = null;
List<GridReservable> reserved = new ArrayList<>();
try {
if (topVer != null) {
// Reserve primary for topology version or explicit partitions.
if (!reservePartitions(cacheIds, topVer, parts, reserved)) {
sendRetry(node, reqId, segmentId);
return;
}
}
qr = new QueryResults(reqId, qrys.size(), mainCctx != null ? mainCctx.name() : null);
if (nodeRess.put(reqId, segmentId, qr) != null)
throw new IllegalStateException();
// Prepare query context.
GridH2QueryContext qctx = new GridH2QueryContext(ctx.localNodeId(), node.id(), reqId, segmentId, replicated ? REPLICATED : MAP).filter(h2.backupFilter(topVer, parts)).partitionsMap(partsMap).distributedJoinMode(distributedJoinMode).pageSize(pageSize).topologyVersion(topVer).reservations(reserved);
List<GridH2Table> snapshotedTbls = null;
if (!F.isEmpty(tbls)) {
snapshotedTbls = new ArrayList<>(tbls.size());
for (QueryTable tbl : tbls) {
GridH2Table h2Tbl = h2.dataTable(tbl);
Objects.requireNonNull(h2Tbl, tbl.toString());
h2Tbl.snapshotIndexes(qctx, segmentId);
snapshotedTbls.add(h2Tbl);
}
}
Connection conn = h2.connectionForSchema(schemaName);
H2Utils.setupConnection(conn, distributedJoinMode != OFF, enforceJoinOrder);
GridH2QueryContext.set(qctx);
// qctx is set, we have to release reservations inside of it.
reserved = null;
try {
if (nodeRess.cancelled(reqId)) {
GridH2QueryContext.clear(ctx.localNodeId(), node.id(), reqId, qctx.type());
nodeRess.cancelRequest(reqId);
throw new QueryCancelledException();
}
// Run queries.
int qryIdx = 0;
boolean evt = mainCctx != null && ctx.event().isRecordable(EVT_CACHE_QUERY_EXECUTED);
for (GridCacheSqlQuery qry : qrys) {
ResultSet rs = null;
// If we are not the target node for this replicated query, just ignore it.
if (qry.node() == null || (segmentId == 0 && qry.node().equals(ctx.localNodeId()))) {
rs = h2.executeSqlQueryWithTimer(conn, qry.query(), F.asList(qry.parameters(params)), true, timeout, qr.cancels[qryIdx]);
if (evt) {
assert mainCctx != null;
ctx.event().record(new CacheQueryExecutedEvent<>(node, "SQL query executed.", EVT_CACHE_QUERY_EXECUTED, CacheQueryType.SQL.name(), mainCctx.name(), null, qry.query(), null, null, params, node.id(), null));
}
assert rs instanceof JdbcResultSet : rs.getClass();
}
qr.addResult(qryIdx, qry, node.id(), rs, params);
if (qr.canceled) {
qr.result(qryIdx).close();
throw new QueryCancelledException();
}
// Send the first page.
sendNextPage(nodeRess, node, qr, qryIdx, segmentId, pageSize);
qryIdx++;
}
} finally {
GridH2QueryContext.clearThreadLocal();
if (distributedJoinMode == OFF)
qctx.clearContext(false);
if (!F.isEmpty(snapshotedTbls)) {
for (GridH2Table dataTbl : snapshotedTbls) dataTbl.releaseSnapshots();
}
}
} catch (Throwable e) {
if (qr != null) {
nodeRess.remove(reqId, segmentId, qr);
qr.cancel(false);
}
if (X.hasCause(e, GridH2RetryException.class))
sendRetry(node, reqId, segmentId);
else {
U.error(log, "Failed to execute local query.", e);
sendError(node, reqId, e);
if (e instanceof Error)
throw (Error) e;
}
} finally {
if (reserved != null) {
// Release reserved partitions.
for (int i = 0; i < reserved.size(); i++) reserved.get(i).release();
}
}
}
use of org.h2.index.Index in project ignite by apache.
the class DmlAstUtils method selectForUpdate.
/**
* Generate SQL SELECT based on UPDATE's WHERE, LIMIT, etc.
*
* @param update Update statement.
* @param keysParamIdx Index of new param for the array of keys.
* @return SELECT statement.
*/
public static GridSqlSelect selectForUpdate(GridSqlUpdate update, @Nullable Integer keysParamIdx) {
GridSqlSelect mapQry = new GridSqlSelect();
mapQry.from(update.target());
Set<GridSqlTable> tbls = new HashSet<>();
collectAllGridTablesInTarget(update.target(), tbls);
assert tbls.size() == 1 : "Failed to determine target table for UPDATE";
GridSqlTable tbl = tbls.iterator().next();
GridH2Table gridTbl = tbl.dataTable();
assert gridTbl != null : "Failed to determine target grid table for UPDATE";
Column h2KeyCol = gridTbl.getColumn(GridH2AbstractKeyValueRow.KEY_COL);
Column h2ValCol = gridTbl.getColumn(GridH2AbstractKeyValueRow.VAL_COL);
GridSqlColumn keyCol = new GridSqlColumn(h2KeyCol, tbl, h2KeyCol.getName());
keyCol.resultType(GridSqlType.fromColumn(h2KeyCol));
GridSqlColumn valCol = new GridSqlColumn(h2ValCol, tbl, h2ValCol.getName());
valCol.resultType(GridSqlType.fromColumn(h2ValCol));
mapQry.addColumn(keyCol, true);
mapQry.addColumn(valCol, true);
for (GridSqlColumn c : update.cols()) {
String newColName = Parser.quoteIdentifier("_upd_" + c.columnName());
// We have to use aliases to cover cases when the user
// wants to update _val field directly (if it's a literal)
GridSqlAlias alias = new GridSqlAlias(newColName, elementOrDefault(update.set().get(c.columnName()), c), true);
alias.resultType(c.resultType());
mapQry.addColumn(alias, true);
}
GridSqlElement where = update.where();
if (keysParamIdx != null)
where = injectKeysFilterParam(where, keyCol, keysParamIdx);
mapQry.where(where);
mapQry.limit(update.limit());
return mapQry;
}
use of org.h2.index.Index in project ignite by apache.
the class GridH2Table method doUpdate.
/**
* For testing only.
*
* @param row Row.
* @param del If given row should be deleted from table.
* @return {@code True} if operation succeeded.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("LockAcquiredButNotSafelyReleased")
boolean doUpdate(final GridH2Row row, boolean del) throws IgniteCheckedException {
// Here we assume that each key can't be updated concurrently and case when different indexes
// getting updated from different threads with different rows with the same key is impossible.
GridUnsafeMemory mem = desc == null ? null : desc.memory();
lock(false);
if (mem != null)
desc.guard().begin();
try {
ensureNotDestroyed();
GridH2IndexBase pk = pk();
if (!del) {
assert rowFactory == null || row.link != 0 : row;
// Put to PK.
GridH2Row old = pk.put(row);
if (old == null)
size.increment();
int len = idxs.size();
int i = pkIndexPos;
// Start from 3 because 0 - Scan (don't need to update), 1 - PK hash (already updated), 2 - PK (already updated).
while (++i < len) {
if (!(idxs.get(i) instanceof GridH2IndexBase))
continue;
GridH2IndexBase idx = index(i);
addToIndex(idx, pk, row, old, false);
}
for (GridH2IndexBase idx : tmpIdxs.values()) addToIndex(idx, pk, row, old, true);
} else {
// index(1) is PK, get full row from there (search row here contains only key but no other columns).
GridH2Row old = pk.remove(row);
if (old != null) {
// Start from 3 because 0 - Scan (don't need to update), 1 - PK hash (already updated), 2 - PK (already updated).
for (int i = pkIndexPos + 1, len = idxs.size(); i < len; i++) {
if (!(idxs.get(i) instanceof GridH2IndexBase))
continue;
Row res = index(i).remove(old);
assert eq(pk, res, old) : "\n" + old + "\n" + res + "\n" + i + " -> " + index(i).getName();
}
for (GridH2IndexBase idx : tmpIdxs.values()) idx.remove(old);
size.decrement();
} else
return false;
}
// The snapshot is not actual after update.
if (actualSnapshot != null)
actualSnapshot.set(pk.segmentForRow(row), null);
return true;
} finally {
unlock(false);
if (mem != null)
desc.guard().end();
}
}
Aggregations