use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.AND in project ignite by apache.
the class DdlStatementsProcessor method runDdlStatement.
/**
* Execute DDL statement.
*
* @param sql SQL.
* @param stmt H2 statement to parse and execute.
*/
@SuppressWarnings("unchecked")
public FieldsQueryCursor<List<?>> runDdlStatement(String sql, PreparedStatement stmt) throws IgniteCheckedException {
assert stmt instanceof JdbcPreparedStatement;
IgniteInternalFuture fut = null;
try {
GridSqlStatement stmt0 = new GridSqlQueryParser(false).parse(GridSqlQueryParser.prepared(stmt));
if (stmt0 instanceof GridSqlCreateIndex) {
GridSqlCreateIndex cmd = (GridSqlCreateIndex) stmt0;
GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null)
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName());
assert tbl.rowDescriptor() != null;
QueryIndex newIdx = new QueryIndex();
newIdx.setName(cmd.index().getName());
newIdx.setIndexType(cmd.index().getIndexType());
LinkedHashMap<String, Boolean> flds = new LinkedHashMap<>();
// Let's replace H2's table and property names by those operated by GridQueryProcessor.
GridQueryTypeDescriptor typeDesc = tbl.rowDescriptor().type();
for (Map.Entry<String, Boolean> e : cmd.index().getFields().entrySet()) {
GridQueryProperty prop = typeDesc.property(e.getKey());
if (prop == null)
throw new SchemaOperationException(SchemaOperationException.CODE_COLUMN_NOT_FOUND, e.getKey());
flds.put(prop.name(), e.getValue());
}
newIdx.setFields(flds);
fut = ctx.query().dynamicIndexCreate(tbl.cacheName(), cmd.schemaName(), typeDesc.tableName(), newIdx, cmd.ifNotExists());
} else if (stmt0 instanceof GridSqlDropIndex) {
GridSqlDropIndex cmd = (GridSqlDropIndex) stmt0;
GridH2Table tbl = idx.dataTableForIndex(cmd.schemaName(), cmd.indexName());
if (tbl != null) {
fut = ctx.query().dynamicIndexDrop(tbl.cacheName(), cmd.schemaName(), cmd.indexName(), cmd.ifExists());
} else {
if (cmd.ifExists())
fut = new GridFinishedFuture();
else
throw new SchemaOperationException(SchemaOperationException.CODE_INDEX_NOT_FOUND, cmd.indexName());
}
} else if (stmt0 instanceof GridSqlCreateTable) {
GridSqlCreateTable cmd = (GridSqlCreateTable) stmt0;
if (!F.eq(QueryUtils.DFLT_SCHEMA, cmd.schemaName()))
throw new SchemaOperationException("CREATE TABLE can only be executed on " + QueryUtils.DFLT_SCHEMA + " schema.");
GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl != null) {
if (!cmd.ifNotExists())
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_EXISTS, cmd.tableName());
} else {
ctx.query().dynamicTableCreate(cmd.schemaName(), toQueryEntity(cmd), cmd.templateName(), cmd.atomicityMode(), cmd.backups(), cmd.ifNotExists());
}
} else if (stmt0 instanceof GridSqlDropTable) {
GridSqlDropTable cmd = (GridSqlDropTable) stmt0;
if (!F.eq(QueryUtils.DFLT_SCHEMA, cmd.schemaName()))
throw new SchemaOperationException("DROP TABLE can only be executed on " + QueryUtils.DFLT_SCHEMA + " schema.");
GridH2Table tbl = idx.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null) {
if (!cmd.ifExists())
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName());
} else
ctx.query().dynamicTableDrop(tbl.cacheName(), cmd.tableName(), cmd.ifExists());
} else
throw new IgniteSQLException("Unsupported DDL operation: " + sql, IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
if (fut != null)
fut.get();
QueryCursorImpl<List<?>> resCur = (QueryCursorImpl<List<?>>) new QueryCursorImpl(Collections.singletonList(Collections.singletonList(0L)), null, false);
resCur.fieldsMeta(UPDATE_RESULT_META);
return resCur;
} catch (SchemaOperationException e) {
throw convert(e);
} catch (IgniteSQLException e) {
throw e;
} catch (Exception e) {
throw new IgniteSQLException("Unexpected DLL operation failure: " + e.getMessage(), e);
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.AND in project ignite by apache.
the class DmlAstUtils method getFastUpdateArgs.
/**
* @param update UPDATE statement.
* @return {@code null} if given statement directly updates {@code _val} column with a literal or param value
* and filters by single non expression key (and, optionally, by single non expression value).
*/
public static FastUpdateArguments getFastUpdateArgs(GridSqlUpdate update) {
IgnitePair<GridSqlElement> filter = findKeyValueEqualityCondition(update.where());
if (filter == null)
return null;
if (update.cols().size() != 1)
return null;
Table tbl = update.cols().get(0).column().getTable();
if (!(tbl instanceof GridH2Table))
return null;
GridH2RowDescriptor desc = ((GridH2Table) tbl).rowDescriptor();
if (!desc.isValueColumn(update.cols().get(0).column().getColumnId()))
return null;
GridSqlElement set = update.set().get(update.cols().get(0).columnName());
if (!(set instanceof GridSqlConst || set instanceof GridSqlParameter))
return null;
return new FastUpdateArguments(operandForElement(filter.getKey()), operandForElement(filter.getValue()), operandForElement(set));
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.AND in project ignite by apache.
the class GridSqlQuerySplitter method extractPartitionFromEquality.
/**
* Analyses the equality operation and extracts the partition if possible
*
* @param op AST equality operation.
* @param ctx Kernal Context.
* @return partition info, or {@code null} if none identified
*/
private static CacheQueryPartitionInfo extractPartitionFromEquality(GridSqlOperation op, GridKernalContext ctx) throws IgniteCheckedException {
assert op.operationType() == GridSqlOperationType.EQUAL;
GridSqlElement left = op.child(0);
GridSqlElement right = op.child(1);
if (!(left instanceof GridSqlColumn))
return null;
if (!(right instanceof GridSqlConst) && !(right instanceof GridSqlParameter))
return null;
GridSqlColumn column = (GridSqlColumn) left;
assert column.column().getTable() instanceof GridH2Table;
GridH2Table tbl = (GridH2Table) column.column().getTable();
GridH2RowDescriptor desc = tbl.rowDescriptor();
IndexColumn affKeyCol = tbl.getAffinityKeyColumn();
int colId = column.column().getColumnId();
if ((affKeyCol == null || colId != affKeyCol.column.getColumnId()) && !desc.isKeyColumn(colId))
return null;
if (right instanceof GridSqlConst) {
GridSqlConst constant = (GridSqlConst) right;
return new CacheQueryPartitionInfo(ctx.affinity().partition(tbl.cacheName(), constant.value().getObject()), null, null, -1, -1);
}
GridSqlParameter param = (GridSqlParameter) right;
return new CacheQueryPartitionInfo(-1, tbl.cacheName(), tbl.getName(), column.column().getType(), param.index());
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.AND in project ignite by apache.
the class DmlStatementsProcessor method doDelete.
/**
* Perform DELETE operation on top of results of SELECT.
* @param cctx Cache context.
* @param cursor SELECT results.
* @param pageSize Batch size for streaming, anything <= 0 for single page operations.
* @return Results of DELETE (number of items affected AND keys that failed to be updated).
*/
@SuppressWarnings({ "unchecked", "ConstantConditions", "ThrowableResultOfMethodCallIgnored" })
private UpdateResult doDelete(GridCacheContext cctx, Iterable<List<?>> cursor, int pageSize) throws IgniteCheckedException {
DmlBatchSender sender = new DmlBatchSender(cctx, pageSize, 1);
for (List<?> row : cursor) {
if (row.size() != 2) {
U.warn(log, "Invalid row size on DELETE - expected 2, got " + row.size());
continue;
}
sender.add(row.get(0), new ModifyingEntryProcessor(row.get(1), RMV), 0);
}
sender.flush();
SQLException resEx = sender.error();
if (resEx != null) {
if (!F.isEmpty(sender.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 DELETE some keys because they had been modified concurrently " + "[keys=" + sender.failedKeys() + ']';
SQLException conEx = createJdbcSqlException(msg, IgniteQueryErrorCode.CONCURRENT_UPDATE);
conEx.setNextException(resEx);
resEx = conEx;
}
throw new IgniteSQLException(resEx);
}
return new UpdateResult(sender.updateCount(), sender.failedKeys().toArray());
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.AND 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();
}
}
Aggregations