use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GridSqlQueryParser method parseExpression0.
/**
* @param expression Expression.
* @param calcTypes Calculate types for all the expressions.
* @return Parsed expression.
*/
private GridSqlElement parseExpression0(Expression expression, boolean calcTypes) {
if (expression instanceof ExpressionColumn) {
ExpressionColumn expCol = (ExpressionColumn) expression;
return new GridSqlColumn(expCol.getColumn(), parseTableFilter(expCol.getTableFilter()), SCHEMA_NAME.get(expCol), expCol.getOriginalTableAliasName(), expCol.getColumnName());
}
if (expression instanceof Alias)
return new GridSqlAlias(expression.getAlias(), parseExpression(expression.getNonAliasExpression(), calcTypes), true);
if (expression instanceof ValueExpression)
// == comparison is legit, see ValueExpression#getSQL()
return expression == ValueExpression.getDefault() ? GridSqlKeyword.DEFAULT : new GridSqlConst(expression.getValue(null));
if (expression instanceof Operation) {
Operation operation = (Operation) expression;
Operation.OpType type = OPERATION_TYPE.get(operation);
if (type == Operation.OpType.NEGATE) {
assert OPERATION_RIGHT.get(operation) == null;
return new GridSqlOperation(GridSqlOperationType.NEGATE, parseExpression(OPERATION_LEFT.get(operation), calcTypes));
}
return new GridSqlOperation(mapOperationType(type), parseExpression(OPERATION_LEFT.get(operation), calcTypes), parseExpression(OPERATION_RIGHT.get(operation), calcTypes));
}
if (expression instanceof Comparison) {
Comparison cmp = (Comparison) expression;
GridSqlOperationType opType = COMPARISON_TYPES[COMPARISON_TYPE.get(cmp)];
assert opType != null : COMPARISON_TYPE.get(cmp);
Expression leftExp = COMPARISON_LEFT.get(cmp);
GridSqlElement left = parseExpression(leftExp, calcTypes);
if (opType.childrenCount() == 1)
return new GridSqlOperation(opType, left);
Expression rightExp = COMPARISON_RIGHT.get(cmp);
GridSqlElement right = parseExpression(rightExp, calcTypes);
return new GridSqlOperation(opType, left, right);
}
if (expression instanceof ConditionNot)
return new GridSqlOperation(NOT, parseExpression(expression.getNotIfPossible(null), calcTypes));
if (expression instanceof ConditionAndOr) {
ConditionAndOr andOr = (ConditionAndOr) expression;
int type = ANDOR_TYPE.get(andOr);
assert type == ConditionAndOr.AND || type == ConditionAndOr.OR;
return new GridSqlOperation(type == ConditionAndOr.AND ? AND : OR, parseExpression(ANDOR_LEFT.get(andOr), calcTypes), parseExpression(ANDOR_RIGHT.get(andOr), calcTypes));
}
if (expression instanceof Subquery) {
Query qry = ((Subquery) expression).getQuery();
return parseQueryExpression(qry);
}
if (expression instanceof ConditionIn) {
GridSqlOperation res = new GridSqlOperation(IN);
res.addChild(parseExpression(LEFT_CI.get((ConditionIn) expression), calcTypes));
List<Expression> vals = VALUE_LIST_CI.get((ConditionIn) expression);
for (Expression val : vals) res.addChild(parseExpression(val, calcTypes));
return res;
}
if (expression instanceof ConditionInConstantSet) {
GridSqlOperation res = new GridSqlOperation(IN);
res.addChild(parseExpression(LEFT_CICS.get((ConditionInConstantSet) expression), calcTypes));
List<Expression> vals = VALUE_LIST_CICS.get((ConditionInConstantSet) expression);
for (Expression val : vals) res.addChild(parseExpression(val, calcTypes));
return res;
}
if (expression instanceof ConditionInSelect) {
GridSqlOperation res = new GridSqlOperation(IN);
boolean all = ALL.get((ConditionInSelect) expression);
int compareType = COMPARE_TYPE.get((ConditionInSelect) expression);
assert0(!all, expression);
assert0(compareType == Comparison.EQUAL, expression);
res.addChild(parseExpression(LEFT_CIS.get((ConditionInSelect) expression), calcTypes));
Query qry = QUERY_IN.get((ConditionInSelect) expression);
res.addChild(parseQueryExpression(qry));
return res;
}
if (expression instanceof CompareLike) {
assert0(ESCAPE.get((CompareLike) expression) == null, expression);
boolean regexp = REGEXP_CL.get((CompareLike) expression);
return new GridSqlOperation(regexp ? REGEXP : LIKE, parseExpression(LEFT.get((CompareLike) expression), calcTypes), parseExpression(RIGHT.get((CompareLike) expression), calcTypes));
}
if (expression instanceof Function) {
Function f = (Function) expression;
GridSqlFunction res = new GridSqlFunction(null, f.getName());
if (f.getArgs() != null) {
if (f.getFunctionType() == Function.TABLE || f.getFunctionType() == Function.TABLE_DISTINCT) {
Column[] cols = FUNC_TBL_COLS.get((TableFunction) f);
Expression[] args = f.getArgs();
assert cols.length == args.length;
for (int i = 0; i < cols.length; i++) {
GridSqlElement arg = parseExpression(args[i], calcTypes);
GridSqlAlias alias = new GridSqlAlias(cols[i].getName(), arg, false);
alias.resultType(fromColumn(cols[i]));
res.addChild(alias);
}
} else {
for (Expression arg : f.getArgs()) {
if (arg == null) {
if (f.getFunctionType() != Function.CASE)
throw new IllegalStateException("Function type with null arg: " + f.getFunctionType());
res.addChild(GridSqlPlaceholder.EMPTY);
} else
res.addChild(parseExpression(arg, calcTypes));
}
}
}
if (f.getFunctionType() == Function.CAST || f.getFunctionType() == Function.CONVERT) {
checkTypeSupported(f.getType(), "[expSql=" + f.getSQL() + ']');
res.resultType(fromExpression(f));
}
return res;
}
if (expression instanceof JavaFunction) {
JavaFunction f = (JavaFunction) expression;
FunctionAlias alias = FUNC_ALIAS.get(f);
GridSqlFunction res = new GridSqlFunction(alias.getSchema().getName(), f.getName());
if (f.getArgs() != null) {
for (Expression arg : f.getArgs()) res.addChild(parseExpression(arg, calcTypes));
}
return res;
}
if (expression instanceof Parameter)
return new GridSqlParameter(((Parameter) expression).getIndex());
if (expression instanceof Aggregate) {
Aggregate.AggregateType type = TYPE.get((Aggregate) expression);
if (GridSqlAggregateFunction.isValidType(type)) {
GridSqlAggregateFunction res = new GridSqlAggregateFunction(DISTINCT.get((Aggregate) expression), type);
Expression on = ON.get((Aggregate) expression);
if (on != null)
res.addChild(parseExpression(on, calcTypes));
ArrayList<SelectOrderBy> orders = GROUP_CONCAT_ORDER_LIST.get((Aggregate) expression);
if (!F.isEmpty(orders))
parseGroupConcatOrder(res, orders, calcTypes);
Expression separator = GROUP_CONCAT_SEPARATOR.get((Aggregate) expression);
if (separator != null)
res.setGroupConcatSeparator(parseExpression(separator, calcTypes));
return res;
}
}
if (expression instanceof ExpressionList) {
Expression[] exprs = EXPR_LIST.get((ExpressionList) expression);
GridSqlArray res = new GridSqlArray(exprs.length);
for (Expression expr : exprs) res.addChild(parseExpression(expr, calcTypes));
return res;
}
if (expression instanceof ConditionExists) {
Query qry = QUERY_EXISTS.get((ConditionExists) expression);
GridSqlOperation res = new GridSqlOperation(EXISTS);
res.addChild(parseQueryExpression(qry));
return res;
}
throw new IgniteException("Unsupported expression: " + expression + " [type=" + expression.getClass().getSimpleName() + ']');
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GridSqlQueryParser method tablesForDml.
/**
* Extract all tables participating in DML statement.
*
* @return List of tables participate at query.
* @throws IgniteSQLException in case query contains virtual tables.
*/
public List<GridH2Table> tablesForDml() throws IgniteSQLException {
Collection<?> parserObjects = h2ObjToGridObj.values();
List<GridH2Table> tbls = new ArrayList<>(parserObjects.size());
// check all involved caches
for (Object o : parserObjects) {
if (o instanceof GridSqlMerge)
o = ((GridSqlMerge) o).into();
else if (o instanceof GridSqlInsert)
o = ((GridSqlInsert) o).into();
else if (o instanceof GridSqlUpdate)
o = ((GridSqlUpdate) o).target();
else if (o instanceof GridSqlDelete)
o = ((GridSqlDelete) o).from();
if (o instanceof GridSqlAlias)
o = GridSqlAlias.unwrap((GridSqlAst) o);
if (o instanceof GridSqlTable) {
GridH2Table h2tbl = ((GridSqlTable) o).dataTable();
if (h2tbl == null) {
// Check for virtual tables.
throw new IgniteSQLException("Operation not supported for table '" + ((GridSqlTable) o).tableName() + "'", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
tbls.add(h2tbl);
}
}
return tbls;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GridSqlQueryParser method collectOptimizedTableFiltersOrder.
/**
* @param qry Query.
*/
private void collectOptimizedTableFiltersOrder(Query qry) {
if (qry instanceof SelectUnion) {
collectOptimizedTableFiltersOrder(((SelectUnion) qry).getLeft());
collectOptimizedTableFiltersOrder(((SelectUnion) qry).getRight());
} else {
Select select = (Select) qry;
TableFilter filter = select.getTopTableFilter();
int i = 0;
do {
assert0(filter != null, select);
assert0(filter.getNestedJoin() == null, select);
// Here all the table filters must have generated unique aliases,
// thus we can store them in the same map for all the subqueries.
optimizedTableFilterOrder.put(filter.getTableAlias(), i++);
Table tbl = filter.getTable();
// Go down and collect inside of optimized subqueries.
if (tbl instanceof TableView) {
ViewIndex viewIdx = (ViewIndex) filter.getIndex();
collectOptimizedTableFiltersOrder(viewIdx.getQuery());
}
filter = filter.getJoin();
} while (filter != null);
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GridReduceQueryExecutor method query.
/**
* @param qryId Query ID.
* @param schemaName Schema name.
* @param qry Query.
* @param keepBinary Keep binary.
* @param enforceJoinOrder Enforce join order of tables.
* @param timeoutMillis Timeout in milliseconds.
* @param cancel Query cancel.
* @param params Query parameters.
* @param parts Partitions.
* @param lazy Lazy execution flag.
* @param mvccTracker Query tracker.
* @param dataPageScanEnabled If data page scan is enabled.
* @param pageSize Page size.
* @return Rows iterator.
*/
@SuppressWarnings("IfMayBeConditional")
public Iterator<List<?>> query(long qryId, String schemaName, final GridCacheTwoStepQuery qry, boolean keepBinary, boolean enforceJoinOrder, int timeoutMillis, GridQueryCancel cancel, Object[] params, int[] parts, boolean lazy, MvccQueryTracker mvccTracker, Boolean dataPageScanEnabled, int pageSize) {
assert !qry.mvccEnabled() || mvccTracker != null;
if (pageSize <= 0)
pageSize = Query.DFLT_PAGE_SIZE;
// If explicit partitions are set, but there are no real tables, ignore.
if (!qry.hasCacheIds() && parts != null)
parts = null;
// Partitions are not supported for queries over all replicated caches.
if (parts != null && qry.isReplicatedOnly())
throw new CacheException("Partitions are not supported for replicated caches");
try {
if (qry.mvccEnabled())
checkActive(tx(ctx));
} catch (IgniteTxAlreadyCompletedCheckedException e) {
throw new TransactionAlreadyCompletedException(e.getMessage(), e);
}
final boolean singlePartMode = parts != null && parts.length == 1;
if (F.isEmpty(params))
params = EMPTY_PARAMS;
List<Integer> cacheIds = qry.cacheIds();
List<GridCacheSqlQuery> mapQueries = prepareMapQueries(qry, params, singlePartMode);
final boolean skipMergeTbl = !qry.explain() && qry.skipMergeTable() || singlePartMode;
final long retryTimeout = retryTimeout(timeoutMillis);
final long qryStartTime = U.currentTimeMillis();
ReduceQueryRun lastRun = null;
for (int attempt = 0; ; attempt++) {
ensureQueryNotCancelled(cancel);
if (attempt > 0) {
throttleOnRetry(lastRun, qryStartTime, retryTimeout, attempt);
ensureQueryNotCancelled(cancel);
}
AffinityTopologyVersion topVer = h2.readyTopologyVersion();
// Check if topology has changed while retrying on locked topology.
if (h2.serverTopologyChanged(topVer) && ctx.cache().context().lockedTopologyVersion(null) != null) {
throw new CacheException(new TransactionException("Server topology is changed during query " + "execution inside a transaction. It's recommended to rollback and retry transaction."));
}
ReducePartitionMapResult mapping = createMapping(qry, parts, cacheIds, topVer);
if (// Can't map query.
mapping == null)
// Retry.
continue;
final Collection<ClusterNode> nodes = mapping.nodes();
final Map<ClusterNode, Integer> nodeToSegmentsCnt = createNodeToSegmentsCountMapping(qry, mapping);
assert !F.isEmpty(nodes);
H2PooledConnection conn = h2.connections().connection(schemaName);
final long qryReqId = qryReqIdGen.incrementAndGet();
h2.runningQueryManager().trackRequestId(qryReqId);
boolean release = true;
try {
final ReduceQueryRun r = createReduceQueryRun(conn, mapQueries, nodes, pageSize, nodeToSegmentsCnt, skipMergeTbl, qry.explain(), dataPageScanEnabled);
runs.put(qryReqId, r);
try {
cancel.add(() -> send(nodes, new GridQueryCancelRequest(qryReqId), null, true));
GridH2QueryRequest req = new GridH2QueryRequest().queryId(qryId).requestId(qryReqId).topologyVersion(topVer).pageSize(pageSize).caches(qry.cacheIds()).tables(qry.distributedJoins() ? qry.tables() : null).partitions(convert(mapping.partitionsMap())).queries(mapQueries).parameters(params).flags(queryFlags(qry, enforceJoinOrder, lazy, dataPageScanEnabled)).timeout(timeoutMillis).explicitTimeout(true).schemaName(schemaName);
if (mvccTracker != null)
req.mvccSnapshot(mvccTracker.snapshot());
final C2<ClusterNode, Message, Message> spec = parts == null ? null : new ReducePartitionsSpecializer(mapping.queryPartitionsMap());
boolean retry = false;
if (send(nodes, req, spec, false)) {
awaitAllReplies(r, nodes, cancel);
if (r.hasErrorOrRetry()) {
CacheException err = r.exception();
if (err != null) {
if (err.getCause() instanceof IgniteClientDisconnectedException)
throw err;
else if (QueryUtils.wasCancelled(err))
// Throw correct exception.
throw new QueryCancelledException();
throw err;
}
// If remote node asks us to retry then we have outdated full partition map.
h2.awaitForReadyTopologyVersion(r.retryTopologyVersion());
retry = true;
}
} else
retry = true;
if (retry) {
lastRun = runs.get(qryReqId);
assert lastRun != null;
// Retry.
continue;
}
Iterator<List<?>> resIter;
if (skipMergeTbl) {
resIter = new ReduceIndexIterator(this, nodes, r, qryReqId, qry.distributedJoins(), mvccTracker, ctx.tracing());
release = false;
U.close(conn, log);
} else {
ensureQueryNotCancelled(cancel);
QueryContext qctx = new QueryContext(0, null, null, null, null, true);
H2Utils.setupConnection(conn, qctx, false, enforceJoinOrder);
if (qry.explain())
return explainPlan(conn, qry, params);
GridCacheSqlQuery rdc = qry.reduceQuery();
final PreparedStatement stmt = conn.prepareStatementNoCache(rdc.query());
H2Utils.bindParameters(stmt, F.asList(rdc.parameters(params)));
ReduceH2QueryInfo qryInfo = new ReduceH2QueryInfo(stmt, qry.originalSql(), ctx.localNodeId(), qryId, qryReqId);
ResultSet res = h2.executeSqlQueryWithTimer(stmt, conn, rdc.query(), timeoutMillis, cancel, dataPageScanEnabled, qryInfo);
resIter = new H2FieldsIterator(res, mvccTracker, conn, r.pageSize(), log, h2, qryInfo, ctx.tracing());
conn = null;
// To prevent callback inside finally block;
mvccTracker = null;
}
return new GridQueryCacheObjectsIterator(resIter, h2.objectContext(), keepBinary);
} catch (IgniteCheckedException | RuntimeException e) {
release = true;
if (e instanceof CacheException) {
if (QueryUtils.wasCancelled(e))
throw new CacheException("Failed to run reduce query locally.", new QueryCancelledException());
throw (CacheException) e;
}
Throwable cause = e;
if (e instanceof IgniteCheckedException) {
Throwable disconnectedErr = ((IgniteCheckedException) e).getCause(IgniteClientDisconnectedException.class);
if (disconnectedErr != null)
cause = disconnectedErr;
}
throw new CacheException("Failed to run reduce query locally. " + cause.getMessage(), cause);
} finally {
if (release) {
releaseRemoteResources(nodes, r, qryReqId, qry.distributedJoins(), mvccTracker);
if (!skipMergeTbl) {
for (int i = 0, mapQrys = mapQueries.size(); i < mapQrys; i++) // Drop all merge tables.
fakeTable(null, i).innerTable(null);
}
}
}
} finally {
if (conn != null && release)
U.close(conn, log);
}
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GridReduceQueryExecutor method onNextPage.
/**
* @param node Node.
* @param msg Message.
*/
public void onNextPage(final ClusterNode node, final GridQueryNextPageResponse msg) {
try (TraceSurroundings ignored = MTC.support(ctx.tracing().create(SQL_PAGE_RESP, MTC.span()))) {
final long qryReqId = msg.queryRequestId();
final int qry = msg.query();
final int seg = msg.segmentId();
final ReduceQueryRun r = runs.get(qryReqId);
if (// Already finished with error or canceled.
r == null)
return;
final int pageSize = r.pageSize();
Reducer idx = r.reducers().get(msg.query());
ReduceResultPage page;
try {
page = new ReduceResultPage(ctx, node.id(), msg) {
@Override
public void fetchNextPage() {
if (r.hasErrorOrRetry()) {
if (r.exception() != null)
throw r.exception();
assert r.retryCause() != null;
throw new CacheException(r.retryCause());
}
try {
GridQueryNextPageRequest msg0 = new GridQueryNextPageRequest(qryReqId, qry, seg, pageSize, (byte) GridH2QueryRequest.setDataPageScanEnabled(0, r.isDataPageScanEnabled()));
if (node.isLocal())
h2.mapQueryExecutor().onNextPageRequest(node, msg0);
else
ctx.io().sendToGridTopic(node, GridTopic.TOPIC_QUERY, msg0, GridIoPolicy.QUERY_POOL);
} catch (IgniteCheckedException e) {
throw new CacheException("Failed to fetch data from node: " + node.id(), e);
}
}
};
} catch (Exception e) {
U.error(log, "Error in message.", e);
MTC.span().addTag(ERROR, e::getMessage);
fail(r, node.id(), "Error in message.", GridQueryFailResponse.GENERAL_ERROR);
return;
}
idx.addPage(page);
if (msg.retry() != null)
r.setStateOnRetry(node.id(), msg.retry(), msg.retryCause());
else if (// Count down only on each first page received.
msg.page() == 0)
r.onFirstPage();
}
}
Aggregations