Search in sources :

Example 1 with Index

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);
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.database.CacheDataRow) H2TreeIndex(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex) GridCacheEntryEx(org.apache.ignite.internal.processors.cache.GridCacheEntryEx) GridH2Row(org.apache.ignite.internal.processors.query.h2.opt.GridH2Row) Index(org.h2.index.Index) H2TreeIndex(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex) H2PkHashIndex(org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) H2PkHashIndex(org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex) QueryCursor(org.apache.ignite.cache.query.QueryCursor) Cursor(org.h2.index.Cursor) FieldsQueryCursor(org.apache.ignite.cache.query.FieldsQueryCursor)

Example 2 with Index

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;
}
Also used : Index(org.h2.index.Index) H2PkHashIndex(org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex) Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow) HashSet(java.util.HashSet)

Example 3 with Index

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();
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Connection(java.sql.Connection) GridH2RetryException(org.apache.ignite.internal.processors.query.h2.opt.GridH2RetryException) GridReservable(org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable) QueryTable(org.apache.ignite.internal.processors.cache.query.QueryTable) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) ResultSet(java.sql.ResultSet) JdbcResultSet(org.h2.jdbc.JdbcResultSet) GridCacheSqlQuery(org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery) QueryCancelledException(org.apache.ignite.cache.query.QueryCancelledException) GridH2QueryContext(org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext) JdbcResultSet(org.h2.jdbc.JdbcResultSet)

Example 4 with Index

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;
}
Also used : Column(org.h2.table.Column) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) ValueString(org.h2.value.ValueString) HashSet(java.util.HashSet)

Example 5 with Index

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();
    }
}
Also used : Row(org.h2.result.Row) SearchRow(org.h2.result.SearchRow) GridUnsafeMemory(org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory)

Aggregations

ResultSet (java.sql.ResultSet)77 Index (org.h2.index.Index)75 Statement (java.sql.Statement)64 SimpleResultSet (org.h2.tools.SimpleResultSet)61 SQLException (java.sql.SQLException)60 Value (org.h2.value.Value)58 DbException (org.h2.message.DbException)57 Connection (java.sql.Connection)56 PreparedStatement (java.sql.PreparedStatement)56 Column (org.h2.table.Column)53 IndexColumn (org.h2.table.IndexColumn)45 ArrayList (java.util.ArrayList)31 ValueString (org.h2.value.ValueString)29 Constraint (org.h2.constraint.Constraint)25 Row (org.h2.result.Row)22 MultiVersionIndex (org.h2.index.MultiVersionIndex)19 JdbcConnection (org.h2.jdbc.JdbcConnection)19 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)18 Table (org.h2.table.Table)18 HashSet (java.util.HashSet)17