use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GridSubqueryJoinOptimizer method isSimpleSelect.
/**
* Whether Select query is simple or not.
* <p>
* We call query simple if it is select query (not union) and it has neither having nor grouping,
* has no distinct clause, has no aggregations, has no limits, no sorting, no offset clause.
* Also it is not SELECT FOR UPDATE.
*
* @param subQry Sub query.
* @return {@code true} if it is simple query.
*/
private static boolean isSimpleSelect(GridSqlQuery subQry) {
if (subQry instanceof GridSqlUnion)
return false;
GridSqlSelect select = (GridSqlSelect) subQry;
boolean simple = F.isEmpty(select.sort()) && select.offset() == null && select.limit() == null && !select.isForUpdate() && !select.distinct() && select.havingColumn() < 0 && F.isEmpty(select.groupColumns());
if (!simple)
return false;
for (GridSqlAst col : select.columns(true)) {
if (!(col instanceof GridSqlElement))
continue;
// we have to traverse the tree because there may be such expressions
// like ((MAX(col) - MIN(col)) / COUNT(col)
ASTNodeFinder aggFinder = new ASTNodeFinder(col, (p, c) -> p instanceof GridSqlAggregateFunction);
if (aggFinder.findNext() != null)
return false;
// In case of query like "SELECT * FROM (SELECT i||j FROM t) u;", where subquery contains pure operation
// without an alias, we cannot determine which generated alias in the parent query the original expression
// belongs to. So the best we can do is skip the case.
ASTNodeFinder operationFinder = new ASTNodeFinder(col, (p, c) -> p instanceof GridSqlOperation, ast -> false);
if (operationFinder.findNext() != null)
return false;
}
return true;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class DmlAstUtils method findKeyValueEqualityCondition.
/**
* @param where Element to test.
* @return Whether given element corresponds to {@code WHERE _key = ?}, and key is a literal expressed
* in query or a query param.
*/
@SuppressWarnings("RedundantCast")
private static IgnitePair<GridSqlElement> findKeyValueEqualityCondition(GridSqlElement where) {
if (!(where instanceof GridSqlOperation))
return null;
GridSqlOperation whereOp = (GridSqlOperation) where;
// Does this WHERE limit only by _key?
if (isKeyEqualityCondition(whereOp))
return new IgnitePair<>((GridSqlElement) whereOp.child(1), null);
// Or maybe it limits both by _key and _val?
if (whereOp.operationType() != GridSqlOperationType.AND)
return null;
GridSqlElement left = whereOp.child(0);
GridSqlElement right = whereOp.child(1);
if (!(left instanceof GridSqlOperation && right instanceof GridSqlOperation))
return null;
GridSqlOperation leftOp = (GridSqlOperation) left;
GridSqlOperation rightOp = (GridSqlOperation) right;
if (isKeyEqualityCondition(leftOp)) {
// _key = ? and _val = ?
if (!isValueEqualityCondition(rightOp))
return null;
return new IgnitePair<>((GridSqlElement) leftOp.child(1), (GridSqlElement) rightOp.child(1));
} else if (isKeyEqualityCondition(rightOp)) {
// _val = ? and _key = ?
if (!isValueEqualityCondition(leftOp))
return null;
return new IgnitePair<>((GridSqlElement) rightOp.child(1), (GridSqlElement) leftOp.child(1));
} else
// Neither
return null;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class DmlAstUtils method findParams.
/**
* @param qry Select.
* @param params Parameters.
* @param target Extracted parameters.
* @param paramIdxs Parameter indexes.
* @return Extracted parameters list.
*/
private static List<Object> findParams(GridSqlSelect qry, Object[] params, ArrayList<Object> target, IntArray paramIdxs) {
if (params.length == 0)
return target;
for (GridSqlAst el : qry.columns(false)) findParams((GridSqlElement) el, params, target, paramIdxs);
findParams((GridSqlElement) qry.from(), params, target, paramIdxs);
findParams((GridSqlElement) qry.where(), params, target, paramIdxs);
// Don't search in GROUP BY and HAVING since they expected to be in select list.
findParams((GridSqlElement) qry.limit(), params, target, paramIdxs);
findParams((GridSqlElement) qry.offset(), params, target, paramIdxs);
return target;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class RetryCauseMessageSelfTest method testReplicatedCacheReserveFailureMessage.
/**
* Failed to reserve partitions for query (partition of REPLICATED cache is not in OWNING state)
*/
@Ignore("https://issues.apache.org/jira/browse/IGNITE-7039")
@Test
public void testReplicatedCacheReserveFailureMessage() {
GridMapQueryExecutor mapQryExec = GridTestUtils.getFieldValue(h2Idx, IgniteH2Indexing.class, "mapQryExec");
final GridKernalContext ctx = GridTestUtils.getFieldValue(mapQryExec, GridMapQueryExecutor.class, "ctx");
GridTestUtils.setFieldValue(h2Idx, "mapQryExec", new MockGridMapQueryExecutor() {
@Override
public void onQueryRequest(ClusterNode node, GridH2QueryRequest qryReq) throws IgniteCheckedException {
GridCacheContext<?, ?> cctx = ctx.cache().context().cacheContext(qryReq.caches().get(0));
GridDhtLocalPartition part = cctx.topology().localPartition(0, NONE, false);
AtomicLong aState = GridTestUtils.getFieldValue(part, GridDhtLocalPartition.class, "state");
long stateVal = aState.getAndSet(2);
startedExecutor.onQueryRequest(node, qryReq);
aState.getAndSet(stateVal);
}
}.insertRealExecutor(mapQryExec));
SqlQuery<String, Organization> qry = new SqlQuery<>(Organization.class, ORG_SQL);
qry.setDistributedJoins(true);
try {
orgCache.query(qry).getAll();
} catch (CacheException e) {
assertTrue(e.getMessage().contains("Failed to reserve partitions for query (partition of REPLICATED cache is not in OWNING state) ["));
return;
} finally {
GridTestUtils.setFieldValue(h2Idx, "mapQryExec", mapQryExec);
}
fail();
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.IN in project ignite by apache.
the class GatherPartitionStatistics method recollectPartition.
/**
* Collect some statistics, fix existing in repo and return resulting partition statistics.
*
* @param cctx Cache context to get partition from.
* @param partStat Existing partition statistics to fix or use as a base.
* @param colsToCollect Columns to collect.
* @param colsToRemove Columns to remove.
* @return New partition statistics.
*/
private ObjectPartitionStatisticsImpl recollectPartition(GridCacheContext<?, ?> cctx, ObjectPartitionStatisticsImpl partStat, Map<String, StatisticsColumnConfiguration> colsToCollect, Set<String> colsToRemove) {
CacheGroupContext grp = cctx.group();
GridDhtPartitionTopology top = grp.topology();
AffinityTopologyVersion topVer = top.readyTopologyVersion();
GridDhtLocalPartition locPart = top.localPartition(partId, topVer, false);
if (locPart == null)
throw new GatherStatisticCancelException();
boolean reserved = locPart.reserve();
GridH2Table tbl = gathCtx.table();
ObjectPartitionStatisticsImpl res = null;
try {
if (!reserved || (locPart.state() != OWNING)) {
if (log.isDebugEnabled()) {
log.debug("Partition not owning. Need to retry [part=" + partId + ", tbl=" + tbl.identifier() + ']');
}
throw new GatherStatisticCancelException();
}
Column[] cols = IgniteStatisticsHelper.filterColumns(tbl.getColumns(), colsToCollect.keySet());
ColumnStatisticsCollector[] collectors = new ColumnStatisticsCollector[cols.length];
for (int i = 0; i < cols.length; ++i) {
long colCfgVer = colsToCollect.get(cols[i].getName()).version();
collectors[i] = new ColumnStatisticsCollector(cols[i], tbl::compareTypeSafe, colCfgVer);
}
GridH2RowDescriptor rowDesc = tbl.rowDescriptor();
GridQueryTypeDescriptor typeDesc = rowDesc.type();
try {
int checkInt = CANCELLED_CHECK_INTERVAL;
if (log.isDebugEnabled()) {
log.debug("Start partition scan [part=" + partId + ", tbl=" + gathCtx.table().identifier() + ']');
}
for (CacheDataRow row : grp.offheap().cachePartitionIterator(gathCtx.table().cacheId(), partId, null, false)) {
if (--checkInt == 0) {
if (gathCtx.future().isCancelled())
throw new GatherStatisticCancelException();
checkInt = CANCELLED_CHECK_INTERVAL;
}
if (!typeDesc.matchType(row.value()) || wasExpired(row))
continue;
H2Row h2row = rowDesc.createRow(row);
for (ColumnStatisticsCollector colStat : collectors) colStat.add(h2row.getValue(colStat.col().getColumnId()));
}
} catch (IgniteCheckedException e) {
log.warning(String.format("Unable to collect partition level statistics by %s.%s:%d due to %s", tbl.identifier().schema(), tbl.identifier().table(), partId, e.getMessage()));
throw new IgniteException("Unable to collect partition level statistics", e);
}
Map<String, ColumnStatistics> colStats = Arrays.stream(collectors).collect(Collectors.toMap(csc -> csc.col().getName(), ColumnStatisticsCollector::finish));
// Add existing to full replace existing statistics with new one.
if (partStat != null) {
for (Map.Entry<String, ColumnStatistics> oldColStat : partStat.columnsStatistics().entrySet()) {
if (!colsToRemove.contains(oldColStat.getKey()))
colStats.putIfAbsent(oldColStat.getKey(), oldColStat.getValue());
}
}
res = new ObjectPartitionStatisticsImpl(partId, getRowCount(colStats), locPart.updateCounter(), colStats);
} finally {
if (reserved)
locPart.release();
}
statRepo.replaceLocalPartitionStatistics(gathCtx.configuration().key(), res);
if (gathCtx.configuration().columns().size() == colsToCollect.size())
statRepo.refreshObsolescence(gathCtx.configuration().key(), partId);
return res;
}
Aggregations