Search in sources :

Example 6 with Select

use of org.h2.command.dml.Select 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 7 with Select

use of org.h2.command.dml.Select in project ignite by apache.

the class DmlAstUtils method selectForDelete.

/**
     * Generate SQL SELECT based on DELETE's WHERE, LIMIT, etc.
     *
     * @param del Delete statement.
     * @param keysParamIdx Index for .
     * @return SELECT statement.
     */
public static GridSqlSelect selectForDelete(GridSqlDelete del, @Nullable Integer keysParamIdx) {
    GridSqlSelect mapQry = new GridSqlSelect();
    mapQry.from(del.from());
    Set<GridSqlTable> tbls = new HashSet<>();
    collectAllGridTablesInTarget(del.from(), tbls);
    assert tbls.size() == 1 : "Failed to determine target table for DELETE";
    GridSqlTable tbl = tbls.iterator().next();
    GridH2Table gridTbl = tbl.dataTable();
    assert gridTbl != null : "Failed to determine target grid table for DELETE";
    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);
    GridSqlElement where = del.where();
    if (keysParamIdx != null)
        where = injectKeysFilterParam(where, keyCol, keysParamIdx);
    mapQry.where(where);
    mapQry.limit(del.limit());
    return mapQry;
}
Also used : Column(org.h2.table.Column) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) HashSet(java.util.HashSet)

Example 8 with Select

use of org.h2.command.dml.Select in project ignite by apache.

the class DmlStatementsProcessor method doUpdate.

/**
     * Perform UPDATE operation on top of results of SELECT.
     * @param cursor SELECT results.
     * @param pageSize Batch size for streaming, anything <= 0 for single page operations.
     * @return Pair [cursor corresponding to results of UPDATE (contains number of items affected); keys whose values
     *     had been modified concurrently (arguments for a re-run)].
     */
@SuppressWarnings({ "unchecked", "ThrowableResultOfMethodCallIgnored" })
private UpdateResult doUpdate(UpdatePlan plan, Iterable<List<?>> cursor, int pageSize) throws IgniteCheckedException {
    GridH2RowDescriptor desc = plan.tbl.rowDescriptor();
    GridCacheContext cctx = desc.context();
    boolean bin = cctx.binaryMarshaller();
    String[] updatedColNames = plan.colNames;
    int valColIdx = plan.valColIdx;
    boolean hasNewVal = (valColIdx != -1);
    // Statement updates distinct properties if it does not have _val in updated columns list
    // or if its list of updated columns includes only _val, i.e. is single element.
    boolean hasProps = !hasNewVal || updatedColNames.length > 1;
    long res = 0;
    Map<Object, EntryProcessor<Object, Object, Boolean>> rows = new LinkedHashMap<>();
    // Keys that failed to UPDATE due to concurrent updates.
    List<Object> failedKeys = new ArrayList<>();
    SQLException resEx = null;
    Iterator<List<?>> it = cursor.iterator();
    while (it.hasNext()) {
        List<?> e = it.next();
        Object key = e.get(0);
        Object newVal;
        Map<String, Object> newColVals = new HashMap<>();
        for (int i = 0; i < plan.colNames.length; i++) {
            if (hasNewVal && i == valColIdx - 2)
                continue;
            GridQueryProperty prop = plan.tbl.rowDescriptor().type().property(plan.colNames[i]);
            assert prop != null;
            newColVals.put(plan.colNames[i], convert(e.get(i + 2), desc, prop.type(), plan.colTypes[i]));
        }
        newVal = plan.valSupplier.apply(e);
        if (newVal == null)
            throw new IgniteSQLException("New value for UPDATE must not be null", IgniteQueryErrorCode.NULL_VALUE);
        // Skip key and value - that's why we start off with 3rd column
        for (int i = 0; i < plan.tbl.getColumns().length - DEFAULT_COLUMNS_COUNT; i++) {
            Column c = plan.tbl.getColumn(i + DEFAULT_COLUMNS_COUNT);
            if (desc.isKeyValueOrVersionColumn(c.getColumnId()))
                continue;
            GridQueryProperty prop = desc.type().property(c.getName());
            if (prop.key())
                // Don't get values of key's columns - we won't use them anyway
                continue;
            boolean hasNewColVal = newColVals.containsKey(c.getName());
            if (!hasNewColVal)
                continue;
            Object colVal = newColVals.get(c.getName());
            // UPDATE currently does not allow to modify key or its fields, so we must be safe to pass null as key.
            desc.setColumnValue(null, newVal, colVal, i);
        }
        if (bin && hasProps) {
            assert newVal instanceof BinaryObjectBuilder;
            newVal = ((BinaryObjectBuilder) newVal).build();
        }
        Object srcVal = e.get(1);
        if (bin && !(srcVal instanceof BinaryObject))
            srcVal = cctx.grid().binary().toBinary(srcVal);
        rows.put(key, new ModifyingEntryProcessor(srcVal, new EntryValueUpdater(newVal)));
        if ((pageSize > 0 && rows.size() == pageSize) || (!it.hasNext())) {
            PageProcessingResult pageRes = processPage(cctx, rows);
            res += pageRes.cnt;
            failedKeys.addAll(F.asList(pageRes.errKeys));
            if (pageRes.ex != null) {
                if (resEx == null)
                    resEx = pageRes.ex;
                else
                    resEx.setNextException(pageRes.ex);
            }
            if (it.hasNext())
                // No need to clear after the last batch.
                rows.clear();
        }
    }
    if (resEx != null) {
        if (!F.isEmpty(failedKeys)) {
            // Don't go for a re-run if processing of some keys yielded exceptions and report keys that
            // had been modified concurrently right away.
            String msg = "Failed to UPDATE some keys because they had been modified concurrently " + "[keys=" + failedKeys + ']';
            SQLException dupEx = createJdbcSqlException(msg, IgniteQueryErrorCode.CONCURRENT_UPDATE);
            dupEx.setNextException(resEx);
            resEx = dupEx;
        }
        throw new IgniteSQLException(resEx);
    }
    return new UpdateResult(res, failedKeys.toArray());
}
Also used : SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) GridBoundedConcurrentLinkedHashMap(org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) GridBoundedConcurrentLinkedHashMap(org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) BinaryObject(org.apache.ignite.binary.BinaryObject) Column(org.h2.table.Column) List(java.util.List) ArrayList(java.util.ArrayList) BinaryObjectBuilder(org.apache.ignite.binary.BinaryObjectBuilder) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridQueryProperty(org.apache.ignite.internal.processors.query.GridQueryProperty) EntryProcessor(javax.cache.processor.EntryProcessor) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) BinaryObject(org.apache.ignite.binary.BinaryObject)

Example 9 with Select

use of org.h2.command.dml.Select in project ignite by apache.

the class DmlStatementsProcessor method getPlanForStatement.

/**
     * Generate SELECT statements to retrieve data for modifications from and find fast UPDATE or DELETE args,
     * if available.
     *
     * @param schema Schema.
     * @param prepStmt JDBC statement.
     * @return Update plan.
     */
@SuppressWarnings({ "unchecked", "ConstantConditions" })
private UpdatePlan getPlanForStatement(String schema, PreparedStatement prepStmt, @Nullable Integer errKeysPos) throws IgniteCheckedException {
    Prepared p = GridSqlQueryParser.prepared(prepStmt);
    H2DmlPlanKey planKey = new H2DmlPlanKey(schema, p.getSQL());
    UpdatePlan res = (errKeysPos == null ? planCache.get(planKey) : null);
    if (res != null)
        return res;
    res = UpdatePlanBuilder.planForStatement(p, errKeysPos);
    // Don't cache re-runs
    if (errKeysPos == null)
        return U.firstNotNull(planCache.putIfAbsent(planKey, res), res);
    else
        return res;
}
Also used : Prepared(org.h2.command.Prepared) UpdatePlan(org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan)

Example 10 with Select

use of org.h2.command.dml.Select in project che by eclipse.

the class H2DBTestServer method start.

@Override
public void start() {
    final JdbcDataSource dataSource = new JdbcDataSource();
    dataSource.setUrl(getUrl() + ";DB_CLOSE_DELAY=-1");
    try (Connection conn = dataSource.getConnection()) {
        RunScript.execute(conn, new StringReader("SELECT 1"));
    } catch (SQLException x) {
        throw new RuntimeException(x);
    }
}
Also used : SQLException(java.sql.SQLException) JdbcDataSource(org.h2.jdbcx.JdbcDataSource) Connection(java.sql.Connection) StringReader(java.io.StringReader)

Aggregations

ResultSet (java.sql.ResultSet)8 PreparedStatement (java.sql.PreparedStatement)6 Statement (java.sql.Statement)5 SimpleResultSet (org.h2.tools.SimpleResultSet)5 ArrayList (java.util.ArrayList)4 Select (org.h2.command.dml.Select)4 ValueString (org.h2.value.ValueString)4 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)3 Column (org.h2.table.Column)3 TableFilter (org.h2.table.TableFilter)3 Connection (java.sql.Connection)2 SQLException (java.sql.SQLException)2 HashSet (java.util.HashSet)2 List (java.util.List)2 UUID (java.util.UUID)2 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)2 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)2 Prepared (org.h2.command.Prepared)2 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)2 SelectUnion (org.h2.command.dml.SelectUnion)2