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;
}
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;
}
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());
}
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;
}
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);
}
}
Aggregations