Search in sources :

Example 1 with GridH2QueryContext

use of org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext 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 2 with GridH2QueryContext

use of org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext in project ignite by apache.

the class IgniteH2Indexing method queryDistributedSqlFields.

/** {@inheritDoc} */
@Override
public FieldsQueryCursor<List<?>> queryDistributedSqlFields(String schemaName, SqlFieldsQuery qry, boolean keepBinary, GridQueryCancel cancel, @Nullable Integer mainCacheId) {
    final String sqlQry = qry.getSql();
    Connection c = connectionForSchema(schemaName);
    final boolean enforceJoinOrder = qry.isEnforceJoinOrder();
    final boolean distributedJoins = qry.isDistributedJoins();
    final boolean grpByCollocated = qry.isCollocated();
    final DistributedJoinMode distributedJoinMode = distributedJoinMode(qry.isLocal(), distributedJoins);
    GridCacheTwoStepQuery twoStepQry = null;
    List<GridQueryFieldMetadata> meta;
    final H2TwoStepCachedQueryKey cachedQryKey = new H2TwoStepCachedQueryKey(schemaName, sqlQry, grpByCollocated, distributedJoins, enforceJoinOrder, qry.isLocal());
    H2TwoStepCachedQuery cachedQry = twoStepCache.get(cachedQryKey);
    if (cachedQry != null) {
        twoStepQry = cachedQry.query().copy();
        meta = cachedQry.meta();
    } else {
        final UUID locNodeId = ctx.localNodeId();
        // Here we will just parse the statement, no need to optimize it at all.
        H2Utils.setupConnection(c, /*distributedJoins*/
        false, /*enforceJoinOrder*/
        true);
        GridH2QueryContext.set(new GridH2QueryContext(locNodeId, locNodeId, 0, PREPARE).distributedJoinMode(distributedJoinMode));
        PreparedStatement stmt = null;
        Prepared prepared;
        boolean cachesCreated = false;
        try {
            try {
                while (true) {
                    try {
                        // Do not cache this statement because the whole query object will be cached later on.
                        stmt = prepareStatement(c, sqlQry, false);
                        break;
                    } catch (SQLException e) {
                        if (!cachesCreated && (e.getErrorCode() == ErrorCode.SCHEMA_NOT_FOUND_1 || e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1 || e.getErrorCode() == ErrorCode.INDEX_NOT_FOUND_1)) {
                            try {
                                ctx.cache().createMissingQueryCaches();
                            } catch (IgniteCheckedException ignored) {
                                throw new CacheException("Failed to create missing caches.", e);
                            }
                            cachesCreated = true;
                        } else
                            throw new IgniteSQLException("Failed to parse query: " + sqlQry, IgniteQueryErrorCode.PARSING, e);
                    }
                }
                prepared = GridSqlQueryParser.prepared(stmt);
                if (qry instanceof JdbcSqlFieldsQuery && ((JdbcSqlFieldsQuery) qry).isQuery() != prepared.isQuery())
                    throw new IgniteSQLException("Given statement type does not match that declared by JDBC driver", IgniteQueryErrorCode.STMT_TYPE_MISMATCH);
                if (prepared.isQuery()) {
                    bindParameters(stmt, F.asList(qry.getArgs()));
                    twoStepQry = GridSqlQuerySplitter.split((JdbcPreparedStatement) stmt, qry.getArgs(), grpByCollocated, distributedJoins, enforceJoinOrder, this);
                    assert twoStepQry != null;
                }
            } finally {
                GridH2QueryContext.clearThreadLocal();
            }
            // It is a DML statement if we did not create a twoStepQuery.
            if (twoStepQry == null) {
                if (DmlStatementsProcessor.isDmlStatement(prepared)) {
                    try {
                        return dmlProc.updateSqlFieldsDistributed(schemaName, stmt, qry, cancel);
                    } catch (IgniteCheckedException e) {
                        throw new IgniteSQLException("Failed to execute DML statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
                    }
                }
                if (DdlStatementsProcessor.isDdlStatement(prepared)) {
                    try {
                        return ddlProc.runDdlStatement(sqlQry, stmt);
                    } catch (IgniteCheckedException e) {
                        throw new IgniteSQLException("Failed to execute DDL statement [stmt=" + sqlQry + ']', e);
                    }
                }
            }
            LinkedHashSet<Integer> caches0 = new LinkedHashSet<>();
            assert twoStepQry != null;
            int tblCnt = twoStepQry.tablesCount();
            if (mainCacheId != null)
                caches0.add(mainCacheId);
            if (tblCnt > 0) {
                for (QueryTable tblKey : twoStepQry.tables()) {
                    GridH2Table tbl = dataTable(tblKey);
                    int cacheId = CU.cacheId(tbl.cacheName());
                    caches0.add(cacheId);
                }
            }
            if (caches0.isEmpty())
                twoStepQry.local(true);
            else {
                //Prohibit usage indices with different numbers of segments in same query.
                List<Integer> cacheIds = new ArrayList<>(caches0);
                checkCacheIndexSegmentation(cacheIds);
                twoStepQry.cacheIds(cacheIds);
                twoStepQry.local(qry.isLocal());
            }
            meta = H2Utils.meta(stmt.getMetaData());
        } catch (IgniteCheckedException e) {
            throw new CacheException("Failed to bind parameters: [qry=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
        } catch (SQLException e) {
            throw new IgniteSQLException(e);
        } finally {
            U.close(stmt, log);
        }
    }
    if (log.isDebugEnabled())
        log.debug("Parsed query: `" + sqlQry + "` into two step query: " + twoStepQry);
    twoStepQry.pageSize(qry.getPageSize());
    if (cancel == null)
        cancel = new GridQueryCancel();
    int[] partitions = qry.getPartitions();
    if (partitions == null && twoStepQry.derivedPartitions() != null) {
        try {
            partitions = calculateQueryPartitions(twoStepQry.derivedPartitions(), qry.getArgs());
        } catch (IgniteCheckedException e) {
            throw new CacheException("Failed to calculate derived partitions: [qry=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
        }
    }
    QueryCursorImpl<List<?>> cursor = new QueryCursorImpl<>(runQueryTwoStep(schemaName, twoStepQry, keepBinary, enforceJoinOrder, qry.getTimeout(), cancel, qry.getArgs(), partitions), cancel);
    cursor.fieldsMeta(meta);
    if (cachedQry == null && !twoStepQry.explain()) {
        cachedQry = new H2TwoStepCachedQuery(meta, twoStepQry.copy());
        twoStepCache.putIfAbsent(cachedQryKey, cachedQry);
    }
    return cursor;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) CacheException(javax.cache.CacheException) Prepared(org.h2.command.Prepared) ArrayList(java.util.ArrayList) GridCacheTwoStepQuery(org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery) GridQueryFieldMetadata(org.apache.ignite.internal.processors.query.GridQueryFieldMetadata) IgniteSystemProperties.getString(org.apache.ignite.IgniteSystemProperties.getString) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) ArrayList(java.util.ArrayList) List(java.util.List) UUID(java.util.UUID) JdbcPreparedStatement(org.h2.jdbc.JdbcPreparedStatement) GridH2QueryContext(org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) JdbcPreparedStatement(org.h2.jdbc.JdbcPreparedStatement) QueryCursorImpl(org.apache.ignite.internal.processors.cache.QueryCursorImpl) QueryTable(org.apache.ignite.internal.processors.cache.query.QueryTable) IgniteSystemProperties.getInteger(org.apache.ignite.IgniteSystemProperties.getInteger) DistributedJoinMode(org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridQueryCancel(org.apache.ignite.internal.processors.query.GridQueryCancel) JdbcSqlFieldsQuery(org.apache.ignite.internal.jdbc2.JdbcSqlFieldsQuery)

Example 3 with GridH2QueryContext

use of org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext in project ignite by apache.

the class IgniteH2Indexing method queryLocalSql.

/**
     * Executes regular query.
     *
     * @param schemaName Schema name.
     * @param qry Query.
     * @param alias Table alias.
     * @param params Query parameters.
     * @param type Query return type.
     * @param filter Cache name and key filter.
     * @return Queried rows.
     * @throws IgniteCheckedException If failed.
     */
@SuppressWarnings("unchecked")
public <K, V> GridCloseableIterator<IgniteBiTuple<K, V>> queryLocalSql(String schemaName, final String qry, String alias, @Nullable final Collection<Object> params, String type, final IndexingQueryFilter filter, GridQueryCancel cancel) throws IgniteCheckedException {
    final H2TableDescriptor tbl = tableDescriptor(schemaName, type);
    if (tbl == null)
        throw new IgniteSQLException("Failed to find SQL table for type: " + type, IgniteQueryErrorCode.TABLE_NOT_FOUND);
    String sql = generateQuery(qry, alias, tbl);
    Connection conn = connectionForThread(tbl.schemaName());
    H2Utils.setupConnection(conn, false, false);
    GridH2QueryContext.set(new GridH2QueryContext(nodeId, nodeId, 0, LOCAL).filter(filter).distributedJoinMode(OFF));
    GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, SQL, schemaName, U.currentTimeMillis(), null, true);
    runs.put(run.id(), run);
    try {
        ResultSet rs = executeSqlQueryWithTimer(conn, sql, params, true, 0, cancel);
        return new H2KeyValueIterator(rs);
    } finally {
        GridH2QueryContext.clearThreadLocal();
        runs.remove(run.id());
    }
}
Also used : IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) Connection(java.sql.Connection) GridRunningQueryInfo(org.apache.ignite.internal.processors.query.GridRunningQueryInfo) ResultSet(java.sql.ResultSet) IgniteSystemProperties.getString(org.apache.ignite.IgniteSystemProperties.getString) GridH2QueryContext(org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext)

Example 4 with GridH2QueryContext

use of org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext in project ignite by apache.

the class IgniteH2Indexing method queryLocalSqlFields.

/**
     * Queries individual fields (generally used by JDBC drivers).
     *
     * @param schemaName Schema name.
     * @param qry Query.
     * @param params Query parameters.
     * @param filter Cache name and key filter.
     * @param enforceJoinOrder Enforce join order of tables in the query.
     * @param timeout Query timeout in milliseconds.
     * @param cancel Query cancel.
     * @return Query result.
     * @throws IgniteCheckedException If failed.
     */
@SuppressWarnings("unchecked")
public GridQueryFieldsResult queryLocalSqlFields(final String schemaName, final String qry, @Nullable final Collection<Object> params, final IndexingQueryFilter filter, boolean enforceJoinOrder, final int timeout, final GridQueryCancel cancel) throws IgniteCheckedException {
    final Connection conn = connectionForSchema(schemaName);
    H2Utils.setupConnection(conn, false, enforceJoinOrder);
    final PreparedStatement stmt = preparedStatementWithParams(conn, qry, params, true);
    Prepared p = GridSqlQueryParser.prepared(stmt);
    if (DmlStatementsProcessor.isDmlStatement(p)) {
        SqlFieldsQuery fldsQry = new SqlFieldsQuery(qry);
        if (params != null)
            fldsQry.setArgs(params.toArray());
        fldsQry.setEnforceJoinOrder(enforceJoinOrder);
        fldsQry.setTimeout(timeout, TimeUnit.MILLISECONDS);
        return dmlProc.updateSqlFieldsLocal(schemaName, stmt, fldsQry, filter, cancel);
    } else if (DdlStatementsProcessor.isDdlStatement(p))
        throw new IgniteSQLException("DDL statements are supported for the whole cluster only", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    List<GridQueryFieldMetadata> meta;
    try {
        meta = H2Utils.meta(stmt.getMetaData());
    } catch (SQLException e) {
        throw new IgniteCheckedException("Cannot prepare query metadata", e);
    }
    final GridH2QueryContext ctx = new GridH2QueryContext(nodeId, nodeId, 0, LOCAL).filter(filter).distributedJoinMode(OFF);
    return new GridQueryFieldsResultAdapter(meta, null) {

        @Override
        public GridCloseableIterator<List<?>> iterator() throws IgniteCheckedException {
            assert GridH2QueryContext.get() == null;
            GridH2QueryContext.set(ctx);
            GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, SQL_FIELDS, schemaName, U.currentTimeMillis(), cancel, true);
            runs.putIfAbsent(run.id(), run);
            try {
                ResultSet rs = executeSqlQueryWithTimer(stmt, conn, qry, params, timeout, cancel);
                return new H2FieldsIterator(rs);
            } finally {
                GridH2QueryContext.clearThreadLocal();
                runs.remove(run.id());
            }
        }
    };
}
Also used : GridQueryFieldsResultAdapter(org.apache.ignite.internal.processors.query.GridQueryFieldsResultAdapter) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) Connection(java.sql.Connection) Prepared(org.h2.command.Prepared) GridRunningQueryInfo(org.apache.ignite.internal.processors.query.GridRunningQueryInfo) GridQueryFieldMetadata(org.apache.ignite.internal.processors.query.GridQueryFieldMetadata) PreparedStatement(java.sql.PreparedStatement) JdbcPreparedStatement(org.h2.jdbc.JdbcPreparedStatement) SqlFieldsQuery(org.apache.ignite.cache.query.SqlFieldsQuery) JdbcSqlFieldsQuery(org.apache.ignite.internal.jdbc2.JdbcSqlFieldsQuery) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) GridH2QueryContext(org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext)

Example 5 with GridH2QueryContext

use of org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext in project ignite by apache.

the class GridH2IndexBase method createRequest.

/**
     * @param qctx Query context.
     * @param batchLookupId Batch lookup ID.
     * @param segmentId Segment ID.
     * @return Index range request.
     */
private static GridH2IndexRangeRequest createRequest(GridH2QueryContext qctx, int batchLookupId, int segmentId) {
    GridH2IndexRangeRequest req = new GridH2IndexRangeRequest();
    req.originNodeId(qctx.originNodeId());
    req.queryId(qctx.queryId());
    req.originSegmentId(qctx.segment());
    req.segment(segmentId);
    req.batchLookupId(batchLookupId);
    return req;
}
Also used : GridH2IndexRangeRequest(org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2IndexRangeRequest)

Aggregations

GridH2QueryContext (org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext)5 Connection (java.sql.Connection)4 ResultSet (java.sql.ResultSet)4 ArrayList (java.util.ArrayList)4 List (java.util.List)3 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)3 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)3 PreparedStatement (java.sql.PreparedStatement)2 SQLException (java.sql.SQLException)2 UUID (java.util.UUID)2 CacheException (javax.cache.CacheException)2 IgniteSystemProperties.getString (org.apache.ignite.IgniteSystemProperties.getString)2 QueryCancelledException (org.apache.ignite.cache.query.QueryCancelledException)2 JdbcSqlFieldsQuery (org.apache.ignite.internal.jdbc2.JdbcSqlFieldsQuery)2 GridCacheSqlQuery (org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery)2 QueryTable (org.apache.ignite.internal.processors.cache.query.QueryTable)2 GridQueryFieldMetadata (org.apache.ignite.internal.processors.query.GridQueryFieldMetadata)2 GridRunningQueryInfo (org.apache.ignite.internal.processors.query.GridRunningQueryInfo)2 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)2 Prepared (org.h2.command.Prepared)2