use of org.h2.command.Command in project ignite by apache.
the class IgniteH2Indexing method doRunPrepared.
/**
* Execute an all-ready {@link SqlFieldsQuery}.
* @param schemaName Schema name.
* @param prepared H2 command.
* @param qry Fields query with flags.
* @param twoStepQry Two-step query if this query must be executed in a distributed way.
* @param meta Metadata for {@code twoStepQry}.
* @param keepBinary Whether binary objects must not be deserialized automatically.
* @param cancel Query cancel state holder. @return Query result.
*/
private List<? extends FieldsQueryCursor<List<?>>> doRunPrepared(String schemaName, Prepared prepared, SqlFieldsQuery qry, GridCacheTwoStepQuery twoStepQry, List<GridQueryFieldMetadata> meta, boolean keepBinary, GridQueryCancel cancel) {
String sqlQry = qry.getSql();
boolean loc = qry.isLocal();
IndexingQueryFilter filter = (loc ? backupFilter(null, qry.getPartitions()) : null);
if (!prepared.isQuery()) {
if (DmlStatementsProcessor.isDmlStatement(prepared)) {
try {
Connection conn = connectionForSchema(schemaName);
if (!loc)
return dmlProc.updateSqlFieldsDistributed(schemaName, conn, prepared, qry, cancel);
else {
final GridQueryFieldsResult updRes = dmlProc.updateSqlFieldsLocal(schemaName, conn, prepared, qry, filter, cancel);
return Collections.singletonList(new QueryCursorImpl<>(new Iterable<List<?>>() {
@Override
public Iterator<List<?>> iterator() {
try {
return new GridQueryCacheObjectsIterator(updRes.iterator(), objectContext(), true);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
}, cancel));
}
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to execute DML statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
}
}
if (DdlStatementsProcessor.isDdlStatement(prepared)) {
if (loc)
throw new IgniteSQLException("DDL statements are not supported for LOCAL caches", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
try {
return Collections.singletonList(ddlProc.runDdlStatement(sqlQry, prepared));
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to execute DDL statement [stmt=" + sqlQry + ']', e);
}
}
if (prepared instanceof NoOperation) {
QueryCursorImpl<List<?>> resCur = (QueryCursorImpl<List<?>>) new QueryCursorImpl(Collections.singletonList(Collections.singletonList(0L)), null, false);
resCur.fieldsMeta(UPDATE_RESULT_META);
return Collections.singletonList(resCur);
}
throw new IgniteSQLException("Unsupported DDL/DML operation: " + prepared.getClass().getName());
}
if (twoStepQry != null) {
if (log.isDebugEnabled())
log.debug("Parsed query: `" + sqlQry + "` into two step query: " + twoStepQry);
checkQueryType(qry, true);
return Collections.singletonList(doRunDistributedQuery(schemaName, qry, twoStepQry, meta, keepBinary, cancel));
}
// We've encountered a local query, let's just run it.
try {
return Collections.singletonList(queryLocalSqlFields(schemaName, qry, keepBinary, filter, cancel));
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to execute local statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
}
}
use of org.h2.command.Command in project ignite by apache.
the class IgniteH2Indexing method parseAndSplit.
/**
* Parse and split query if needed, cache either two-step query or statement.
* @param schemaName Schema name.
* @param qry Query.
* @param firstArg Position of the first argument of the following {@code Prepared}.
* @return Result: prepared statement, H2 command, two-step query (if needed),
* metadata for two-step query (if needed), evaluated query local execution flag.
*/
private ParsingResult parseAndSplit(String schemaName, SqlFieldsQuery qry, int firstArg) {
Connection c = connectionForSchema(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());
H2Utils.setupConnection(c, /*distributedJoins*/
false, /*enforceJoinOrder*/
enforceJoinOrderOnParsing);
boolean loc = qry.isLocal();
PreparedStatement stmt = prepareStatementAndCaches(c, qry.getSql());
if (loc && GridSqlQueryParser.checkMultipleStatements(stmt))
throw new IgniteSQLException("Multiple statements queries are not supported for local queries");
GridSqlQueryParser.PreparedWithRemaining prep = GridSqlQueryParser.preparedWithRemaining(stmt);
Prepared prepared = prep.prepared();
checkQueryType(qry, prepared.isQuery());
String remainingSql = prep.remainingSql();
int paramsCnt = prepared.getParameters().size();
Object[] argsOrig = qry.getArgs();
Object[] args = null;
if (!DmlUtils.isBatched(qry) && paramsCnt > 0) {
if (argsOrig == null || argsOrig.length < firstArg + paramsCnt) {
throw new IgniteException("Invalid number of query parameters. " + "Cannot find " + (argsOrig != null ? argsOrig.length + 1 - firstArg : 1) + " parameter.");
}
args = Arrays.copyOfRange(argsOrig, firstArg, firstArg + paramsCnt);
}
if (prepared.isQuery()) {
try {
bindParameters(stmt, F.asList(args));
} catch (IgniteCheckedException e) {
U.closeQuiet(stmt);
throw new IgniteSQLException("Failed to bind parameters: [qry=" + prepared.getSQL() + ", params=" + Arrays.deepToString(args) + "]", IgniteQueryErrorCode.PARSING, e);
}
GridSqlQueryParser parser = null;
if (!loc) {
parser = new GridSqlQueryParser(false);
GridSqlStatement parsedStmt = parser.parse(prepared);
// Legit assertion - we have H2 query flag above.
assert parsedStmt instanceof GridSqlQuery;
loc = parser.isLocalQuery(qry.isReplicatedOnly());
}
if (loc) {
if (parser == null) {
parser = new GridSqlQueryParser(false);
parser.parse(prepared);
}
GridCacheContext cctx = parser.getFirstPartitionedCache();
if (cctx != null && cctx.config().getQueryParallelism() > 1) {
loc = false;
qry.setDistributedJoins(true);
}
}
}
SqlFieldsQuery newQry = cloneFieldsQuery(qry).setSql(prepared.getSQL()).setArgs(args);
boolean hasTwoStep = !loc && prepared.isQuery();
// Let's not cache multiple statements and distributed queries as whole two step query will be cached later on.
if (remainingSql != null || hasTwoStep)
getStatementsCacheForCurrentThread().remove(schemaName, qry.getSql());
if (!hasTwoStep)
return new ParsingResult(prepared, newQry, remainingSql, null, null, null);
final UUID locNodeId = ctx.localNodeId();
// Now we're sure to have a distributed query. Let's try to get a two-step plan from the cache, or perform the
// split if needed.
H2TwoStepCachedQueryKey cachedQryKey = new H2TwoStepCachedQueryKey(schemaName, qry.getSql(), qry.isCollocated(), qry.isDistributedJoins(), qry.isEnforceJoinOrder(), qry.isLocal());
H2TwoStepCachedQuery cachedQry;
if ((cachedQry = twoStepCache.get(cachedQryKey)) != null) {
checkQueryType(qry, true);
GridCacheTwoStepQuery twoStepQry = cachedQry.query().copy();
List<GridQueryFieldMetadata> meta = cachedQry.meta();
return new ParsingResult(prepared, newQry, remainingSql, twoStepQry, cachedQryKey, meta);
}
try {
GridH2QueryContext.set(new GridH2QueryContext(locNodeId, locNodeId, 0, PREPARE).distributedJoinMode(distributedJoinMode(qry.isLocal(), qry.isDistributedJoins())));
try {
return new ParsingResult(prepared, newQry, remainingSql, split(prepared, newQry), cachedQryKey, H2Utils.meta(stmt.getMetaData()));
} catch (IgniteCheckedException e) {
throw new IgniteSQLException("Failed to bind parameters: [qry=" + newQry.getSql() + ", params=" + Arrays.deepToString(newQry.getArgs()) + "]", IgniteQueryErrorCode.PARSING, e);
} catch (SQLException e) {
throw new IgniteSQLException(e);
} finally {
U.close(stmt, log);
}
} finally {
GridH2QueryContext.clearThreadLocal();
}
}
use of org.h2.command.Command in project ignite by apache.
the class GridH2Table method addColumns.
/**
* Add new columns to this table.
*
* @param cols Columns to add.
* @param ifNotExists Ignore this command if {@code cols} has size of 1 and column with given name already exists.
*/
public void addColumns(List<QueryField> cols, boolean ifNotExists) {
assert !ifNotExists || cols.size() == 1;
lock(true);
try {
int pos = columns.length;
Column[] newCols = new Column[columns.length + cols.size()];
// First, let's copy existing columns to new array
System.arraycopy(columns, 0, newCols, 0, columns.length);
// And now, let's add new columns
for (QueryField col : cols) {
if (doesColumnExist(col.name())) {
if (ifNotExists && cols.size() == 1)
return;
else
throw new IgniteSQLException("Column already exists [tblName=" + getName() + ", colName=" + col.name() + ']');
}
try {
Column c = new Column(col.name(), DataType.getTypeFromClass(Class.forName(col.typeName())));
c.setNullable(col.isNullable());
newCols[pos++] = c;
} catch (ClassNotFoundException e) {
throw new IgniteSQLException("H2 data type not found for class: " + col.typeName(), e);
}
}
setColumns(newCols);
desc.refreshMetadataFromTypeDescriptor();
setModified();
} finally {
unlock(true);
}
}
use of org.h2.command.Command in project h2database by h2database.
the class Parser method parseAlterUser.
private AlterUser parseAlterUser() {
String userName = readUniqueIdentifier();
if (readIf("SET")) {
AlterUser command = new AlterUser(session);
command.setType(CommandInterface.ALTER_USER_SET_PASSWORD);
command.setUser(database.getUser(userName));
if (readIf("PASSWORD")) {
command.setPassword(readExpression());
} else if (readIf("SALT")) {
command.setSalt(readExpression());
read("HASH");
command.setHash(readExpression());
} else {
throw getSyntaxError();
}
return command;
} else if (readIf("RENAME")) {
read("TO");
AlterUser command = new AlterUser(session);
command.setType(CommandInterface.ALTER_USER_RENAME);
command.setUser(database.getUser(userName));
String newName = readUniqueIdentifier();
command.setNewName(newName);
return command;
} else if (readIf("ADMIN")) {
AlterUser command = new AlterUser(session);
command.setType(CommandInterface.ALTER_USER_ADMIN);
User user = database.getUser(userName);
command.setUser(user);
if (readIf("TRUE")) {
command.setAdmin(true);
} else if (readIf("FALSE")) {
command.setAdmin(false);
} else {
throw getSyntaxError();
}
return command;
}
throw getSyntaxError();
}
use of org.h2.command.Command in project h2database by h2database.
the class Parser method parseSetCollation.
private Set parseSetCollation() {
Set command = new Set(session, SetTypes.COLLATION);
String name = readAliasIdentifier();
command.setString(name);
if (equalsToken(name, CompareMode.OFF)) {
return command;
}
Collator coll = CompareMode.getCollator(name);
if (coll == null) {
throw DbException.getInvalidValueException("collation", name);
}
if (readIf("STRENGTH")) {
if (readIf("PRIMARY")) {
command.setInt(Collator.PRIMARY);
} else if (readIf("SECONDARY")) {
command.setInt(Collator.SECONDARY);
} else if (readIf("TERTIARY")) {
command.setInt(Collator.TERTIARY);
} else if (readIf("IDENTICAL")) {
command.setInt(Collator.IDENTICAL);
}
} else {
command.setInt(coll.getStrength());
}
return command;
}
Aggregations