Search in sources :

Example 31 with IN

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

the class PartitionExtractor method extractSingle.

/**
 * Extract single partition.
 *
 * @param leftCol Left column.
 * @param rightConst Right constant.
 * @param rightParam Right parameter.
 * @param tblModel Table model.
 * @return Partition or {@code null} if failed to extract.
 */
@Nullable
private PartitionSingleNode extractSingle(GridSqlColumn leftCol, GridSqlConst rightConst, GridSqlParameter rightParam, PartitionTableModel tblModel) throws IgniteCheckedException {
    assert leftCol != null;
    Column leftCol0 = leftCol.column();
    assert leftCol0.getTable() != null;
    assert leftCol0.getTable() instanceof GridH2Table;
    GridH2Table tbl = (GridH2Table) leftCol0.getTable();
    if (!tbl.isColumnForPartitionPruning(leftCol0))
        return null;
    PartitionTable tbl0 = tblModel.table(leftCol.tableAlias());
    // If table is in ignored set, then we cannot use it for partition extraction.
    if (tbl0 == null)
        return null;
    if (rightConst != null) {
        int part = partResolver.partition(rightConst.value().getObject(), leftCol0.getType(), tbl.cacheName());
        return new PartitionConstantNode(tbl0, part);
    } else if (rightParam != null) {
        int colType = leftCol0.getType();
        return new PartitionParameterNode(tbl0, partResolver, rightParam.index(), leftCol0.getType(), mappedType(colType));
    } else
        return null;
}
Also used : PartitionTable(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTable) Column(org.h2.table.Column) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) PartitionParameterNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionParameterNode) PartitionConstantNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionConstantNode) Nullable(org.jetbrains.annotations.Nullable)

Example 32 with IN

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

the class PartitionExtractor method prepareTableModel0.

/**
 * Prepare tables which will be used in join model.
 *
 * @param from From flag.
 * @param model Table model.
 * @return {@code True} if extracted tables successfully, {@code false} if failed to extract.
 */
private List<PartitionTable> prepareTableModel0(GridSqlAst from, PartitionTableModel model) {
    if (from instanceof GridSqlJoin) {
        // Process JOIN recursively.
        GridSqlJoin join = (GridSqlJoin) from;
        List<PartitionTable> leftTbls = prepareTableModel0(join.leftTable(), model);
        List<PartitionTable> rightTbls = prepareTableModel0(join.rightTable(), model);
        if (join.isLeftOuter()) {
            // If a condition is met on "b" afterwards, we will ignore it.
            for (PartitionTable rightTbl : rightTbls) model.addExcludedTable(rightTbl.alias());
            return leftTbls;
        }
        // Extract equi-join or cross-join from condition. For normal INNER JOINs most likely we will have "1=1"
        // cross join here, real join condition will be found in WHERE clause later.
        PartitionJoinCondition cond = parseJoinCondition(join.on());
        if (cond != null && !cond.cross())
            model.addJoin(cond);
        ArrayList<PartitionTable> res = new ArrayList<>(leftTbls.size() + rightTbls.size());
        res.addAll(leftTbls);
        res.addAll(rightTbls);
        return res;
    }
    PartitionTable tbl = prepareTable(from, model);
    return tbl != null ? Collections.singletonList(tbl) : Collections.emptyList();
}
Also used : PartitionTable(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTable) PartitionJoinCondition(org.apache.ignite.internal.sql.optimizer.affinity.PartitionJoinCondition) GridSqlJoin(org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin) ArrayList(java.util.ArrayList)

Example 33 with IN

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

the class DmlUtils method dmlDoInsert.

/**
 * Execute INSERT statement plan.
 * @param cursor Cursor to take inserted data from.
 * @param pageSize Batch size for streaming, anything <= 0 for single page operations.
 * @return Number of items affected.
 * @throws IgniteCheckedException if failed, particularly in case of duplicate keys.
 */
@SuppressWarnings({ "unchecked" })
private static long dmlDoInsert(UpdatePlan plan, Iterable<List<?>> cursor, int pageSize) throws IgniteCheckedException {
    GridCacheContext cctx = plan.cacheContext();
    // If we have just one item to put, just do so
    if (plan.rowCount() == 1) {
        IgniteBiTuple t = plan.processRow(cursor.iterator().next());
        try (MTC.TraceSurroundings ignored = MTC.support(cctx.kernalContext().tracing().create(SQL_CACHE_UPDATE, MTC.span()).addTag(SQL_CACHE_UPDATES, () -> "1"))) {
            if (cctx.cache().putIfAbsent(t.getKey(), t.getValue()))
                return 1;
            else
                throw new TransactionDuplicateKeyException("Duplicate key during INSERT [key=" + t.getKey() + ']');
        }
    } else {
        // Keys that failed to INSERT due to duplication.
        DmlBatchSender sender = new DmlBatchSender(cctx, pageSize, 1);
        for (List<?> row : cursor) {
            final IgniteBiTuple keyValPair = plan.processRow(row);
            sender.add(keyValPair.getKey(), new DmlStatementsProcessor.InsertEntryProcessor(keyValPair.getValue()), 0);
        }
        sender.flush();
        SQLException resEx = sender.error();
        if (!F.isEmpty(sender.failedKeys())) {
            String msg = "Failed to INSERT some keys because they are already in cache " + "[keys=" + sender.failedKeys() + ']';
            SQLException dupEx = new SQLException(msg, SqlStateCode.CONSTRAINT_VIOLATION);
            if (resEx == null)
                resEx = dupEx;
            else
                resEx.setNextException(dupEx);
        }
        if (resEx != null)
            throw new IgniteSQLException(resEx);
        return sender.updateCount();
    }
}
Also used : TransactionDuplicateKeyException(org.apache.ignite.transactions.TransactionDuplicateKeyException) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) DmlStatementsProcessor(org.apache.ignite.internal.processors.query.h2.DmlStatementsProcessor) MTC(org.apache.ignite.internal.processors.tracing.MTC)

Example 34 with IN

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

the class DmlUtils method doInsertBatched.

/**
 * Execute INSERT statement plan.
 *
 * @param plan Plan to execute.
 * @param cursor Cursor to take inserted data from. I.e. list of batch arguments for each query.
 * @param pageSize Batch size for streaming, anything <= 0 for single page operations.
 * @return Number of items affected.
 * @throws IgniteCheckedException if failed, particularly in case of duplicate keys.
 */
private static List<UpdateResult> doInsertBatched(UpdatePlan plan, List<List<List<?>>> cursor, int pageSize) throws IgniteCheckedException {
    GridCacheContext cctx = plan.cacheContext();
    DmlBatchSender snd = new DmlBatchSender(cctx, pageSize, cursor.size());
    int rowNum = 0;
    SQLException resEx = null;
    for (List<List<?>> qryRow : cursor) {
        for (List<?> row : qryRow) {
            try {
                final IgniteBiTuple keyValPair = plan.processRow(row);
                snd.add(keyValPair.getKey(), new DmlStatementsProcessor.InsertEntryProcessor(keyValPair.getValue()), rowNum);
            } catch (Exception e) {
                String sqlState;
                int code;
                if (e instanceof IgniteSQLException) {
                    sqlState = ((IgniteSQLException) e).sqlState();
                    code = ((IgniteSQLException) e).statusCode();
                } else {
                    sqlState = SqlStateCode.INTERNAL_ERROR;
                    code = IgniteQueryErrorCode.UNKNOWN;
                }
                resEx = chainException(resEx, new SQLException(e.getMessage(), sqlState, code, e));
                snd.setFailed(rowNum);
            }
        }
        rowNum++;
    }
    try {
        snd.flush();
    } catch (Exception e) {
        resEx = chainException(resEx, new SQLException(e.getMessage(), SqlStateCode.INTERNAL_ERROR, IgniteQueryErrorCode.UNKNOWN, e));
    }
    resEx = chainException(resEx, snd.error());
    if (!F.isEmpty(snd.failedKeys())) {
        SQLException e = new SQLException("Failed to INSERT some keys because they are already in cache [keys=" + snd.failedKeys() + ']', SqlStateCode.CONSTRAINT_VIOLATION, DUPLICATE_KEY);
        resEx = chainException(resEx, e);
    }
    if (resEx != null) {
        BatchUpdateException e = new BatchUpdateException(resEx.getMessage(), resEx.getSQLState(), resEx.getErrorCode(), snd.perRowCounterAsArray(), resEx);
        throw new IgniteCheckedException(e);
    }
    int[] cntPerRow = snd.perRowCounterAsArray();
    List<UpdateResult> res = new ArrayList<>(cntPerRow.length);
    for (int i = 0; i < cntPerRow.length; i++) {
        int cnt = cntPerRow[i];
        res.add(new UpdateResult(cnt, X.EMPTY_OBJECT_ARRAY));
    }
    return res;
}
Also used : GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) ArrayList(java.util.ArrayList) BatchUpdateException(java.sql.BatchUpdateException) IgniteQueryErrorCode.createJdbcSqlException(org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.createJdbcSqlException) SQLException(java.sql.SQLException) TransactionDuplicateKeyException(org.apache.ignite.transactions.TransactionDuplicateKeyException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) ArrayList(java.util.ArrayList) List(java.util.List) DmlStatementsProcessor(org.apache.ignite.internal.processors.query.h2.DmlStatementsProcessor) UpdateResult(org.apache.ignite.internal.processors.query.h2.UpdateResult) BatchUpdateException(java.sql.BatchUpdateException)

Example 35 with IN

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

the class DmlAstUtils method selectForUpdate.

/**
 * Generate SQL SELECT based on UPDATE's WHERE, LIMIT, etc.
 *
 * @param update Update statement.
 * @return SELECT statement.
 */
public static GridSqlSelect selectForUpdate(GridSqlUpdate update) {
    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(QueryUtils.KEY_COL);
    Column h2ValCol = gridTbl.getColumn(QueryUtils.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();
    // On no MVCC mode we cannot use lazy mode when UPDATE query contains index with updated columns
    // and that index may be chosen to scan by WHERE condition
    // because in this case any rows update may be updated several times.
    // e.g. in the cases below we cannot use lazy mode:
    // 
    // 1. CREATE INDEX idx on test(val)
    // UPDATE test SET val = val + 1 WHERE val >= ?
    // 
    // 2. CREATE INDEX idx on test(val0, val1)
    // UPDATE test SET val1 = val1 + 1 WHERE val0 >= ?
    mapQry.canBeLazy(!isIndexWithUpdateColumnsMayBeUsed(gridTbl, update.cols().stream().map(GridSqlColumn::column).collect(Collectors.toSet()), extractColumns(gridTbl, where)));
    mapQry.where(where);
    mapQry.limit(update.limit());
    return mapQry;
}
Also used : GridSqlAlias(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) Column(org.h2.table.Column) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) ValueString(org.h2.value.ValueString) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) HashSet(java.util.HashSet)

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