Search in sources :

Example 1 with PartitionResult

use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult in project ignite by apache.

the class JdbcThinPartitionAwarenessSelfTest method verifyPartitionResultIsNull.

/**
 * Utility method that executes given query and verifies that expected number of records was returned.
 * Besides that given method verified that partition result for corresponding query is null.
 *
 * @param sqlQry Sql query.
 * @param expRowsCnt Expected rows count.
 * @throws SQLException If failed.
 */
protected void verifyPartitionResultIsNull(String sqlQry, int expRowsCnt) throws SQLException {
    ResultSet rs = stmt.executeQuery(sqlQry);
    assert rs != null;
    int rowCntr = 0;
    while (rs.next()) rowCntr++;
    assertEquals("Rows counter doesn't match expected value.", expRowsCnt, rowCntr);
    AffinityCache affinityCache = GridTestUtils.getFieldValue(conn, "affinityCache");
    PartitionResult gotPartRes = affinityCache.partitionResult(new QualifiedSQLQuery("default", sqlQry)).partitionResult();
    assertNull("Partition result descriptor is not null.", gotPartRes);
}
Also used : AffinityCache(org.apache.ignite.internal.jdbc.thin.AffinityCache) ResultSet(java.sql.ResultSet) QualifiedSQLQuery(org.apache.ignite.internal.jdbc.thin.QualifiedSQLQuery) PartitionResult(org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult)

Example 2 with PartitionResult

use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult in project ignite by apache.

the class PartitionExtractor method mergeMapQueries.

/**
 * Merge partition info from multiple queries.
 *
 * @param qrys Queries.
 * @return Partition result or {@code null} if nothing is resolved.
 */
@SuppressWarnings("IfMayBeConditional")
public PartitionResult mergeMapQueries(List<GridCacheSqlQuery> qrys) {
    // Check if merge is possible.
    PartitionTableAffinityDescriptor aff = null;
    for (GridCacheSqlQuery qry : qrys) {
        PartitionResult qryRes = (PartitionResult) qry.derivedPartitions();
        // Failed to get results for one query -> broadcast.
        if (qryRes == null)
            return null;
        // This only possible if query is resolved to "NONE". Will be skipped later during map request prepare.
        if (qryRes.affinity() == null)
            continue;
        if (aff == null)
            aff = qryRes.affinity();
        else if (!aff.isCompatible(qryRes.affinity()))
            // Queries refer to incompatible affinity groups, cannot merge -> broadcast.
            return null;
    }
    // Merge.
    PartitionNode tree = null;
    AffinityTopologyVersion affinityTopVer = null;
    for (GridCacheSqlQuery qry : qrys) {
        PartitionResult qryRes = (PartitionResult) qry.derivedPartitions();
        if (tree == null)
            tree = qryRes.tree();
        else
            tree = new PartitionCompositeNode(tree, qryRes.tree(), PartitionCompositeNodeOperator.OR);
        if (affinityTopVer == null)
            affinityTopVer = qryRes.topologyVersion();
        else
            assert affinityTopVer.equals(qryRes.topologyVersion());
    }
    // Optimize.
    assert tree != null;
    tree = tree.optimize();
    if (tree instanceof PartitionAllNode)
        return null;
    // If there is no affinity, then we assume "NONE" result.
    assert aff != null || tree == PartitionNoneNode.INSTANCE;
    // TODO: during PartitionResult construction/application.
    assert affinityTopVer != null;
    return new PartitionResult(tree, aff, affinityTopVer);
}
Also used : PartitionAllNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionAllNode) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) PartitionNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionNode) GridCacheSqlQuery(org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery) PartitionResult(org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult) PartitionCompositeNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionCompositeNode) PartitionTableAffinityDescriptor(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTableAffinityDescriptor)

Example 3 with PartitionResult

use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult in project ignite by apache.

the class IgniteH2Indexing method executeUpdate.

/**
 * Execute DML statement, possibly with few re-attempts in case of concurrent data modifications.
 *
 * @param qryId Query id.
 * @param qryDesc Query descriptor.
 * @param qryParams Query parameters.
 * @param dml DML command.
 * @param loc Query locality flag.
 * @param filters Cache name and key filter.
 * @param cancel Cancel.
 * @return Update result (modified items count and failed keys).
 * @throws IgniteCheckedException if failed.
 */
@SuppressWarnings("IfMayBeConditional")
private UpdateResult executeUpdate(long qryId, QueryDescriptor qryDesc, QueryParameters qryParams, QueryParserResultDml dml, boolean loc, IndexingQueryFilter filters, GridQueryCancel cancel) throws IgniteCheckedException {
    Object[] errKeys = null;
    long items = 0;
    PartitionResult partRes = null;
    GridCacheContext<?, ?> cctx = dml.plan().cacheContext();
    boolean transactional = cctx != null && cctx.mvccEnabled();
    int maxRetryCnt = transactional ? 1 : DFLT_UPDATE_RERUN_ATTEMPTS;
    for (int i = 0; i < maxRetryCnt; i++) {
        CacheOperationContext opCtx = cctx != null ? DmlUtils.setKeepBinaryContext(cctx) : null;
        UpdateResult r;
        try {
            if (transactional)
                r = executeUpdateTransactional(qryId, qryDesc, qryParams, dml, loc, cancel);
            else
                r = executeUpdateNonTransactional(qryId, qryDesc, qryParams, dml, loc, filters, cancel);
        } finally {
            if (opCtx != null)
                DmlUtils.restoreKeepBinaryContext(cctx, opCtx);
        }
        items += r.counter();
        errKeys = r.errorKeys();
        partRes = r.partitionResult();
        if (F.isEmpty(errKeys))
            break;
    }
    if (F.isEmpty(errKeys) && partRes == null) {
        if (items == 1L)
            return UpdateResult.ONE;
        else if (items == 0L)
            return UpdateResult.ZERO;
    }
    return new UpdateResult(items, errKeys, partRes);
}
Also used : CacheOperationContext(org.apache.ignite.internal.processors.cache.CacheOperationContext) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) PartitionResult(org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult)

Example 4 with PartitionResult

use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult in project ignite by apache.

the class IgniteH2Indexing method executeSelectDistributed.

/**
 * Run distributed query on detected set of partitions.
 *
 * @param qryId Query id.
 * @param qryDesc Query descriptor.
 * @param qryParams Query parameters.
 * @param twoStepQry Two-step query.
 * @param keepBinary Keep binary flag.
 * @param mvccTracker Query tracker.
 * @param cancel Cancel handler.
 * @param timeout Timeout.
 * @return Cursor representing distributed query result.
 */
@SuppressWarnings("IfMayBeConditional")
private Iterable<List<?>> executeSelectDistributed(final long qryId, final QueryDescriptor qryDesc, final QueryParameters qryParams, final GridCacheTwoStepQuery twoStepQry, final boolean keepBinary, MvccQueryTracker mvccTracker, final GridQueryCancel cancel, int timeout) {
    // When explicit partitions are set, there must be an owning cache they should be applied to.
    PartitionResult derivedParts = twoStepQry.derivedPartitions();
    final int[] parts = PartitionResult.calculatePartitions(qryParams.partitions(), derivedParts, qryParams.arguments());
    Iterable<List<?>> iter;
    if (parts != null && parts.length == 0) {
        iter = new Iterable<List<?>>() {

            @Override
            public Iterator<List<?>> iterator() {
                return new Iterator<List<?>>() {

                    @Override
                    public boolean hasNext() {
                        return false;
                    }

                    @SuppressWarnings("IteratorNextCanNotThrowNoSuchElementException")
                    @Override
                    public List<?> next() {
                        return null;
                    }
                };
            }
        };
    } else {
        assert !twoStepQry.mvccEnabled() || !F.isEmpty(twoStepQry.cacheIds());
        assert twoStepQry.mvccEnabled() == (mvccTracker != null);
        iter = new Iterable<List<?>>() {

            @Override
            public Iterator<List<?>> iterator() {
                try (TraceSurroundings ignored = MTC.support(ctx.tracing().create(SQL_ITER_OPEN, MTC.span()))) {
                    return IgniteH2Indexing.this.rdcQryExec.query(qryId, qryDesc.schemaName(), twoStepQry, keepBinary, qryDesc.enforceJoinOrder(), timeout, cancel, qryParams.arguments(), parts, qryParams.lazy(), mvccTracker, qryParams.dataPageScanEnabled(), qryParams.pageSize());
                } catch (Throwable e) {
                    if (mvccTracker != null)
                        mvccTracker.onDone();
                    throw e;
                }
            }
        };
    }
    return iter;
}
Also used : GridQueryCacheObjectsIterator(org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator) UpdateSourceIterator(org.apache.ignite.internal.processors.query.UpdateSourceIterator) GridCloseableIterator(org.apache.ignite.internal.util.lang.GridCloseableIterator) GridEmptyCloseableIterator(org.apache.ignite.internal.util.GridEmptyCloseableIterator) DmlUpdateSingleEntryIterator(org.apache.ignite.internal.processors.query.h2.dml.DmlUpdateSingleEntryIterator) DmlUpdateResultsIterator(org.apache.ignite.internal.processors.query.h2.dml.DmlUpdateResultsIterator) IgniteSingletonIterator(org.apache.ignite.internal.util.lang.IgniteSingletonIterator) Iterator(java.util.Iterator) Collections.singletonList(java.util.Collections.singletonList) ArrayList(java.util.ArrayList) List(java.util.List) PartitionResult(org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult) TraceSurroundings(org.apache.ignite.internal.processors.tracing.MTC.TraceSurroundings)

Example 5 with PartitionResult

use of org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult in project ignite by apache.

the class JdbcRequestHandler method executeQuery.

/**
 * {@link JdbcQueryExecuteRequest} command handler.
 *
 * @param req Execute query request.
 * @return Response.
 */
@SuppressWarnings("unchecked")
private JdbcResponse executeQuery(JdbcQueryExecuteRequest req) {
    GridQueryCancel cancel = null;
    boolean unregisterReq = false;
    if (isCancellationSupported()) {
        synchronized (reqMux) {
            JdbcQueryDescriptor desc = reqRegister.get(req.requestId());
            // Query was already cancelled and unregistered.
            if (desc == null)
                return null;
            cancel = desc.cancelHook();
            desc.incrementUsageCount();
        }
    }
    try {
        int cursorCnt = jdbcCursors.size();
        if (maxCursors > 0 && cursorCnt >= maxCursors)
            return new JdbcResponse(IgniteQueryErrorCode.UNKNOWN, "Too many open cursors (either close other " + "open cursors or increase the limit through " + "ClientConnectorConfiguration.maxOpenCursorsPerConnection) [maximum=" + maxCursors + ", current=" + cursorCnt + ']');
        assert !cliCtx.isStream();
        String sql = req.sqlQuery();
        SqlFieldsQueryEx qry;
        switch(req.expectedStatementType()) {
            case ANY_STATEMENT_TYPE:
                qry = new SqlFieldsQueryEx(sql, null);
                break;
            case SELECT_STATEMENT_TYPE:
                qry = new SqlFieldsQueryEx(sql, true);
                break;
            default:
                assert req.expectedStatementType() == JdbcStatementType.UPDATE_STMT_TYPE;
                qry = new SqlFieldsQueryEx(sql, false);
                if (cliCtx.isSkipReducerOnUpdate())
                    ((SqlFieldsQueryEx) qry).setSkipReducerOnUpdate(true);
        }
        setupQuery(qry, prepareSchemaName(req.schemaName()));
        qry.setArgs(req.arguments());
        qry.setAutoCommit(req.autoCommit());
        if (req.explicitTimeout()) {
            // Timeout is handled on a client side, do not handle it on a server side.
            qry.setTimeout(0, TimeUnit.MILLISECONDS);
        }
        if (req.pageSize() <= 0)
            return new JdbcResponse(IgniteQueryErrorCode.UNKNOWN, "Invalid fetch size: " + req.pageSize());
        qry.setPageSize(req.pageSize());
        String schemaName = req.schemaName();
        if (F.isEmpty(schemaName))
            schemaName = QueryUtils.DFLT_SCHEMA;
        qry.setSchema(schemaName);
        List<FieldsQueryCursor<List<?>>> results = connCtx.kernalContext().query().querySqlFields(null, qry, cliCtx, true, protocolVer.compareTo(VER_2_3_0) < 0, cancel);
        FieldsQueryCursor<List<?>> fieldsCur = results.get(0);
        if (fieldsCur instanceof BulkLoadContextCursor) {
            BulkLoadContextCursor blCur = (BulkLoadContextCursor) fieldsCur;
            BulkLoadProcessor blProcessor = blCur.bulkLoadProcessor();
            BulkLoadAckClientParameters clientParams = blCur.clientParams();
            JdbcBulkLoadProcessor processor = new JdbcBulkLoadProcessor(blProcessor, req.requestId());
            jdbcCursors.put(processor.cursorId(), processor);
            // responses for the same query on the client side
            return resultToResonse(new JdbcBulkLoadAckResult(processor.cursorId(), clientParams));
        }
        if (results.size() == 1) {
            JdbcQueryCursor cur = new JdbcQueryCursor(req.pageSize(), req.maxRows(), (QueryCursorImpl) fieldsCur, req.requestId());
            jdbcCursors.put(cur.cursorId(), cur);
            cur.openIterator();
            JdbcQueryExecuteResult res;
            PartitionResult partRes = ((QueryCursorImpl<List<?>>) fieldsCur).partitionResult();
            if (cur.isQuery())
                res = new JdbcQueryExecuteResult(cur.cursorId(), cur.fetchRows(), !cur.hasNext(), isClientPartitionAwarenessApplicable(req.partitionResponseRequest(), partRes) ? partRes : null);
            else {
                List<List<Object>> items = cur.fetchRows();
                assert items != null && items.size() == 1 && items.get(0).size() == 1 && items.get(0).get(0) instanceof Long : "Invalid result set for not-SELECT query. [qry=" + sql + ", res=" + S.toString(List.class, items) + ']';
                res = new JdbcQueryExecuteResult(cur.cursorId(), (Long) items.get(0).get(0), isClientPartitionAwarenessApplicable(req.partitionResponseRequest(), partRes) ? partRes : null);
            }
            if (res.last() && (!res.isQuery() || autoCloseCursors)) {
                jdbcCursors.remove(cur.cursorId());
                unregisterReq = true;
                cur.close();
            }
            return resultToResonse(res);
        } else {
            List<JdbcResultInfo> jdbcResults = new ArrayList<>(results.size());
            List<List<Object>> items = null;
            boolean last = true;
            for (FieldsQueryCursor<List<?>> c : results) {
                QueryCursorImpl qryCur = (QueryCursorImpl) c;
                JdbcResultInfo jdbcRes;
                if (qryCur.isQuery()) {
                    JdbcQueryCursor cur = new JdbcQueryCursor(req.pageSize(), req.maxRows(), qryCur, req.requestId());
                    jdbcCursors.put(cur.cursorId(), cur);
                    jdbcRes = new JdbcResultInfo(true, -1, cur.cursorId());
                    cur.openIterator();
                    if (items == null) {
                        items = cur.fetchRows();
                        last = cur.hasNext();
                    }
                } else
                    jdbcRes = new JdbcResultInfo(false, (Long) ((List<?>) qryCur.getAll().get(0)).get(0), -1);
                jdbcResults.add(jdbcRes);
            }
            return resultToResonse(new JdbcQueryExecuteMultipleStatementsResult(jdbcResults, items, last));
        }
    } catch (Exception e) {
        // Trying to close all cursors of current request.
        clearCursors(req.requestId());
        unregisterReq = true;
        U.error(log, "Failed to execute SQL query [reqId=" + req.requestId() + ", req=" + req + ']', e);
        if (X.cause(e, QueryCancelledException.class) != null)
            return exceptionToResult(new QueryCancelledException());
        else
            return exceptionToResult(e);
    } finally {
        cleanupQueryCancellationMeta(unregisterReq, req.requestId());
    }
}
Also used : FieldsQueryCursor(org.apache.ignite.cache.query.FieldsQueryCursor) ArrayList(java.util.ArrayList) BulkLoadProcessor(org.apache.ignite.internal.processors.bulkload.BulkLoadProcessor) SqlFieldsQueryEx(org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx) List(java.util.List) ArrayList(java.util.ArrayList) PartitionResult(org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult) BulkLoadContextCursor(org.apache.ignite.cache.query.BulkLoadContextCursor) QueryCursorImpl(org.apache.ignite.internal.processors.cache.QueryCursorImpl) QueryCancelledException(org.apache.ignite.cache.query.QueryCancelledException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) BatchUpdateException(java.sql.BatchUpdateException) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) BulkLoadAckClientParameters(org.apache.ignite.internal.processors.bulkload.BulkLoadAckClientParameters) GridQueryCancel(org.apache.ignite.internal.processors.query.GridQueryCancel) QueryCancelledException(org.apache.ignite.cache.query.QueryCancelledException)

Aggregations

PartitionResult (org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult)7 ArrayList (java.util.ArrayList)2 List (java.util.List)2 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)2 PartitionAllNode (org.apache.ignite.internal.sql.optimizer.affinity.PartitionAllNode)2 PartitionNode (org.apache.ignite.internal.sql.optimizer.affinity.PartitionNode)2 BatchUpdateException (java.sql.BatchUpdateException)1 ResultSet (java.sql.ResultSet)1 Savepoint (java.sql.Savepoint)1 Collections.singletonList (java.util.Collections.singletonList)1 Iterator (java.util.Iterator)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 BulkLoadContextCursor (org.apache.ignite.cache.query.BulkLoadContextCursor)1 FieldsQueryCursor (org.apache.ignite.cache.query.FieldsQueryCursor)1 QueryCancelledException (org.apache.ignite.cache.query.QueryCancelledException)1 IgniteInterruptedCheckedException (org.apache.ignite.internal.IgniteInterruptedCheckedException)1 AffinityCache (org.apache.ignite.internal.jdbc.thin.AffinityCache)1 QualifiedSQLQuery (org.apache.ignite.internal.jdbc.thin.QualifiedSQLQuery)1 BulkLoadAckClientParameters (org.apache.ignite.internal.processors.bulkload.BulkLoadAckClientParameters)1 BulkLoadProcessor (org.apache.ignite.internal.processors.bulkload.BulkLoadProcessor)1