Search in sources :

Example 21 with IN

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.

the class StatisticsUtils method toMessage.

/**
 * Convert ColumnStatistics to StaticColumnData message.
 *
 * @param stat Column statistics to convert.
 * @return Converted stats column data message.
 * @throws IgniteCheckedException In case of errors.
 */
public static StatisticsColumnData toMessage(ColumnStatistics stat) throws IgniteCheckedException {
    GridH2ValueMessage msgMin = stat.min() == null ? null : GridH2ValueMessageFactory.toMessage(stat.min());
    GridH2ValueMessage msgMax = stat.max() == null ? null : GridH2ValueMessageFactory.toMessage(stat.max());
    return new StatisticsColumnData(msgMin, msgMax, stat.nulls(), stat.distinct(), stat.total(), stat.size(), stat.raw(), stat.version(), stat.createdAt());
}
Also used : GridH2ValueMessage(org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessage) StatisticsColumnData(org.apache.ignite.internal.processors.query.stat.messages.StatisticsColumnData)

Example 22 with IN

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.

the class ValidateIndexesClosure method processIndex.

/**
 * @param cacheCtxWithIdx Cache context and appropriate index.
 * @param idleChecker Idle check closure.
 */
private Map<String, ValidateIndexesPartitionResult> processIndex(T2<GridCacheContext, Index> cacheCtxWithIdx, IgniteInClosure<Integer> idleChecker) {
    if (validateCtx.isCancelled())
        return emptyMap();
    GridCacheContext ctx = cacheCtxWithIdx.get1();
    Index idx = cacheCtxWithIdx.get2();
    ValidateIndexesPartitionResult idxValidationRes = new ValidateIndexesPartitionResult();
    boolean enoughIssues = false;
    Cursor cursor = null;
    try (Session session = mvccSession(cacheCtxWithIdx.get1())) {
        cursor = idx.find(session, null, null);
        if (cursor == null)
            throw new IgniteCheckedException("Can't iterate through index: " + idx);
    } catch (Throwable t) {
        IndexValidationIssue is = new IndexValidationIssue(null, ctx.name(), idx.getName(), t);
        log.error("Find in index failed: " + is.toString());
        idxValidationRes.reportIssue(is);
        enoughIssues = true;
    }
    final boolean skipConditions = checkFirst > 0 || checkThrough > 0;
    final boolean bothSkipConditions = checkFirst > 0 && checkThrough > 0;
    long current = 0;
    long processedNumber = 0;
    KeyCacheObject previousKey = null;
    while (!enoughIssues && !validateCtx.isCancelled()) {
        KeyCacheObject h2key = null;
        try {
            try {
                if (!cursor.next())
                    break;
            } catch (DbException e) {
                if (X.hasCause(e, CorruptedTreeException.class))
                    throw new IgniteCheckedException("Key is present in SQL index, but is missing in corresponding " + "data page. Previous successfully read key: " + CacheObjectUtils.unwrapBinaryIfNeeded(ctx.cacheObjectContext(), previousKey, true, true), X.cause(e, CorruptedTreeException.class));
                throw e;
            }
            H2CacheRow h2Row = (H2CacheRow) cursor.get();
            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;
                    }
                }
            }
            h2key = h2Row.key();
            if (h2Row.link() != 0L) {
                CacheDataRow cacheDataStoreRow = ctx.group().offheap().read(ctx, h2key);
                if (cacheDataStoreRow == null)
                    throw new IgniteCheckedException("Key is present in SQL index, but can't be found in CacheDataTree.");
            } else
                throw new IgniteCheckedException("Invalid index row, possibly deleted " + h2Row);
        } catch (Throwable t) {
            Object o = CacheObjectUtils.unwrapBinaryIfNeeded(ctx.cacheObjectContext(), h2key, true, true);
            IndexValidationIssue is = new IndexValidationIssue(String.valueOf(o), ctx.name(), idx.getName(), t);
            log.error("Failed to lookup key: " + is.toString());
            enoughIssues |= idxValidationRes.reportIssue(is);
        } finally {
            previousKey = h2key;
        }
    }
    CacheGroupContext group = ctx.group();
    String uniqueIdxName = String.format("[cacheGroup=%s, cacheGroupId=%s, cache=%s, cacheId=%s, idx=%s]", group.name(), group.groupId(), ctx.name(), ctx.cacheId(), idx.getName());
    idleChecker.apply(group.groupId());
    processedIndexes.incrementAndGet();
    printProgressOfIndexValidationIfNeeded();
    return Collections.singletonMap(uniqueIdxName, idxValidationRes);
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) Index(org.h2.index.Index) H2CacheRow(org.apache.ignite.internal.processors.query.h2.opt.H2CacheRow) Cursor(org.h2.index.Cursor) DbException(org.h2.message.DbException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) CorruptedTreeException(org.apache.ignite.internal.processors.cache.persistence.tree.CorruptedTreeException) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) CacheGroupContext(org.apache.ignite.internal.processors.cache.CacheGroupContext) Session(org.h2.engine.Session) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject)

Example 23 with IN

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN 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);
            }
        }
    }
}
Also used : CacheDataRow(org.apache.ignite.internal.processors.cache.persistence.CacheDataRow) QueryTypeDescriptorImpl(org.apache.ignite.internal.processors.query.QueryTypeDescriptorImpl) H2TreeIndexBase(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndexBase) Index(org.h2.index.Index) H2CacheRow(org.apache.ignite.internal.processors.query.h2.opt.H2CacheRow) Cursor(org.h2.index.Cursor) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) IgniteException(org.apache.ignite.IgniteException) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridQueryProcessor(org.apache.ignite.internal.processors.query.GridQueryProcessor) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) IgniteH2Indexing(org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing)

Example 24 with IN

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.

the class QueryParser method parseH2.

/**
 * Parse and split query if needed, cache either two-step query or statement.
 *
 * @param schemaName Schema name.
 * @param qry Query.
 * @param batched Batched flag.
 * @param remainingAllowed Whether multiple statements are allowed.
 * @return Parsing result.
 */
@SuppressWarnings("IfMayBeConditional")
private QueryParserResult parseH2(String schemaName, SqlFieldsQuery qry, boolean batched, boolean remainingAllowed) {
    try (H2PooledConnection c = connMgr.connection(schemaName)) {
        // For queries that are explicitly local, we rely on the flag specified in the query
        // because this parsing result will be cached and used for queries directly.
        // For other queries, we enforce join order at this stage to avoid premature optimizations
        // (and therefore longer parsing) as long as there'll be more parsing at split stage.
        boolean enforceJoinOrderOnParsing = (!qry.isLocal() || qry.isEnforceJoinOrder());
        QueryContext qctx = QueryContext.parseContext(idx.backupFilter(null, null), qry.isLocal());
        H2Utils.setupConnection(c, qctx, false, enforceJoinOrderOnParsing, false);
        PreparedStatement stmt = null;
        try {
            stmt = c.prepareStatementNoCache(qry.getSql());
            if (qry.isLocal() && GridSqlQueryParser.checkMultipleStatements(stmt))
                throw new IgniteSQLException("Multiple statements queries are not supported for local queries.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
            GridSqlQueryParser.PreparedWithRemaining prep = GridSqlQueryParser.preparedWithRemaining(stmt);
            Prepared prepared = prep.prepared();
            if (GridSqlQueryParser.isExplainUpdate(prepared))
                throw new IgniteSQLException("Explains of update queries are not supported.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
            // Get remaining query and check if it is allowed.
            SqlFieldsQuery remainingQry = null;
            if (!F.isEmpty(prep.remainingSql())) {
                checkRemainingAllowed(remainingAllowed);
                remainingQry = cloneFieldsQuery(qry).setSql(prep.remainingSql());
            }
            // Prepare new query.
            SqlFieldsQuery newQry = cloneFieldsQuery(qry).setSql(prepared.getSQL());
            final int paramsCnt = prepared.getParameters().size();
            Object[] argsOrig = qry.getArgs();
            Object[] args = null;
            Object[] remainingArgs = null;
            if (!batched && paramsCnt > 0) {
                if (argsOrig == null || argsOrig.length < paramsCnt)
                    // Not enough parameters, but we will handle this later on execution phase.
                    args = argsOrig;
                else {
                    args = Arrays.copyOfRange(argsOrig, 0, paramsCnt);
                    if (paramsCnt != argsOrig.length)
                        remainingArgs = Arrays.copyOfRange(argsOrig, paramsCnt, argsOrig.length);
                }
            } else
                remainingArgs = argsOrig;
            newQry.setArgs(args);
            QueryDescriptor newQryDesc = queryDescriptor(schemaName, newQry);
            if (remainingQry != null)
                remainingQry.setArgs(remainingArgs);
            final List<JdbcParameterMeta> paramsMeta;
            try {
                paramsMeta = H2Utils.parametersMeta(stmt.getParameterMetaData());
                assert prepared.getParameters().size() == paramsMeta.size();
            } catch (IgniteCheckedException | SQLException e) {
                throw new IgniteSQLException("Failed to get parameters metadata", IgniteQueryErrorCode.UNKNOWN, e);
            }
            // Do actual parsing.
            if (CommandProcessor.isCommand(prepared)) {
                GridSqlStatement cmdH2 = new GridSqlQueryParser(false, log).parse(prepared);
                QueryParserResultCommand cmd = new QueryParserResultCommand(null, cmdH2, false);
                return new QueryParserResult(newQryDesc, queryParameters(newQry), remainingQry, paramsMeta, null, null, cmd);
            } else if (CommandProcessor.isCommandNoOp(prepared)) {
                QueryParserResultCommand cmd = new QueryParserResultCommand(null, null, true);
                return new QueryParserResult(newQryDesc, queryParameters(newQry), remainingQry, paramsMeta, null, null, cmd);
            } else if (GridSqlQueryParser.isDml(prepared)) {
                QueryParserResultDml dml = prepareDmlStatement(newQryDesc, prepared);
                return new QueryParserResult(newQryDesc, queryParameters(newQry), remainingQry, paramsMeta, null, dml, null);
            } else if (!prepared.isQuery()) {
                throw new IgniteSQLException("Unsupported statement: " + newQry.getSql(), IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
            }
            // Parse SELECT.
            GridSqlQueryParser parser = new GridSqlQueryParser(false, log);
            GridSqlQuery selectStmt = (GridSqlQuery) parser.parse(prepared);
            List<Integer> cacheIds = parser.cacheIds();
            Integer mvccCacheId = mvccCacheIdForSelect(parser.objectsMap());
            // Calculate if query is in fact can be executed locally.
            boolean loc = qry.isLocal();
            if (!loc) {
                if (parser.isLocalQuery())
                    loc = true;
            }
            // If this is a local query, check if it must be split.
            boolean locSplit = false;
            if (loc) {
                GridCacheContext cctx = parser.getFirstPartitionedCache();
                if (cctx != null && cctx.config().getQueryParallelism() > 1)
                    locSplit = true;
            }
            // Split is required either if query is distributed, or when it is local, but executed
            // over segmented PARTITIONED case. In this case multiple map queries will be executed against local
            // node stripes in parallel and then merged through reduce process.
            boolean splitNeeded = !loc || locSplit;
            String forUpdateQryOutTx = null;
            String forUpdateQryTx = null;
            GridCacheTwoStepQuery forUpdateTwoStepQry = null;
            boolean forUpdate = GridSqlQueryParser.isForUpdateQuery(prepared);
            // column to be able to lock selected rows further.
            if (forUpdate) {
                // We have checked above that it's not an UNION query, so it's got to be SELECT.
                assert selectStmt instanceof GridSqlSelect;
                // Check FOR UPDATE invariants: only one table, MVCC is there.
                if (cacheIds.size() != 1)
                    throw new IgniteSQLException("SELECT FOR UPDATE is supported only for queries " + "that involve single transactional cache.");
                if (mvccCacheId == null)
                    throw new IgniteSQLException("SELECT FOR UPDATE query requires transactional cache " + "with MVCC enabled.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
                // We need a copy because we are going to modify AST a bit. We do not want to modify original select.
                GridSqlSelect selForUpdate = ((GridSqlSelect) selectStmt).copySelectForUpdate();
                // Clear forUpdate flag to run it as a plain query.
                selForUpdate.forUpdate(false);
                ((GridSqlSelect) selectStmt).forUpdate(false);
                // Remember sql string without FOR UPDATE clause.
                forUpdateQryOutTx = selForUpdate.getSQL();
                GridSqlAlias keyCol = keyColumn(selForUpdate);
                selForUpdate.addColumn(keyCol, true);
                // Remember sql string without FOR UPDATE clause and with _key column.
                forUpdateQryTx = selForUpdate.getSQL();
                // Prepare additional two-step query for FOR UPDATE case.
                if (splitNeeded) {
                    c.schema(newQry.getSchema());
                    forUpdateTwoStepQry = GridSqlQuerySplitter.split(c, selForUpdate, forUpdateQryTx, newQry.isCollocated(), newQry.isDistributedJoins(), newQry.isEnforceJoinOrder(), locSplit, idx, paramsCnt, log);
                }
            }
            GridCacheTwoStepQuery twoStepQry = null;
            if (splitNeeded) {
                GridSubqueryJoinOptimizer.pullOutSubQueries(selectStmt);
                c.schema(newQry.getSchema());
                twoStepQry = GridSqlQuerySplitter.split(c, selectStmt, newQry.getSql(), newQry.isCollocated(), newQry.isDistributedJoins(), newQry.isEnforceJoinOrder(), locSplit, idx, paramsCnt, log);
            }
            List<GridQueryFieldMetadata> meta = H2Utils.meta(stmt.getMetaData());
            QueryParserResultSelect select = new QueryParserResultSelect(selectStmt, twoStepQry, forUpdateTwoStepQry, meta, cacheIds, mvccCacheId, forUpdateQryOutTx, forUpdateQryTx);
            return new QueryParserResult(newQryDesc, queryParameters(newQry), remainingQry, paramsMeta, select, null, null);
        } catch (IgniteCheckedException | SQLException e) {
            throw new IgniteSQLException("Failed to parse query. " + e.getMessage(), IgniteQueryErrorCode.PARSING, e);
        } finally {
            U.close(stmt, log);
        }
    }
}
Also used : GridSqlAlias(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlStatement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement) Prepared(org.h2.command.Prepared) GridCacheTwoStepQuery(org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery) GridQueryFieldMetadata(org.apache.ignite.internal.processors.query.GridQueryFieldMetadata) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) JdbcParameterMeta(org.apache.ignite.internal.processors.odbc.jdbc.JdbcParameterMeta) PreparedStatement(java.sql.PreparedStatement) QueryContext(org.apache.ignite.internal.processors.query.h2.opt.QueryContext) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) SqlFieldsQuery(org.apache.ignite.cache.query.SqlFieldsQuery) GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridSqlQueryParser(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 25 with IN

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.

the class SchemaManager method createIndex.

/**
 * Create index dynamically.
 *
 * @param schemaName Schema name.
 * @param tblName Table name.
 * @param idxDesc Index descriptor.
 * @param ifNotExists If-not-exists.
 * @param cacheVisitor Cache visitor.
 * @throws IgniteCheckedException If failed.
 */
public void createIndex(String schemaName, String tblName, QueryIndexDescriptorImpl idxDesc, boolean ifNotExists, SchemaIndexCacheVisitor cacheVisitor) throws IgniteCheckedException {
    // Locate table.
    H2Schema schema = schema(schemaName);
    H2TableDescriptor desc = (schema != null ? schema.tableByName(tblName) : null);
    if (desc == null)
        throw new IgniteCheckedException("Table not found in internal H2 database [schemaName=" + schemaName + ", tblName=" + tblName + ']');
    GridH2Table h2Tbl = desc.table();
    // Create index.
    final GridH2IndexBase h2Idx = desc.createUserIndex(idxDesc, cacheVisitor);
    h2Tbl.proposeUserIndex(h2Idx);
    try {
        // At this point index is in consistent state, promote it through H2 SQL statement, so that cached
        // prepared statements are re-built.
        String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, ifNotExists);
        connMgr.executeStatement(schemaName, sql);
    } catch (Exception e) {
        // Rollback and re-throw.
        h2Tbl.rollbackUserIndex(h2Idx.getName());
        throw e;
    }
}
Also used : GridH2IndexBase(org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Aggregations

IgniteCheckedException (org.apache.ignite.IgniteCheckedException)35 ArrayList (java.util.ArrayList)29 IgniteException (org.apache.ignite.IgniteException)26 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)26 SQLException (java.sql.SQLException)21 List (java.util.List)21 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)21 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)19 CacheException (javax.cache.CacheException)15 QueryCancelledException (org.apache.ignite.cache.query.QueryCancelledException)13 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)13 Column (org.h2.table.Column)13 IgniteH2Indexing (org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing)10 IgniteBiTuple (org.apache.ignite.lang.IgniteBiTuple)10 ResultSet (java.sql.ResultSet)9 HashMap (java.util.HashMap)9 CacheDataRow (org.apache.ignite.internal.processors.cache.persistence.CacheDataRow)9 GridSqlSelect (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)9 PreparedStatement (java.sql.PreparedStatement)8 HashSet (java.util.HashSet)8