use of org.apache.ignite.internal.processors.query.GridQueryFieldMetadata in project ignite by apache.
the class IgniteCacheProxyImpl method queryContinuous.
/**
* Executes continuous query.
*
* @param qry Query.
* @param loc Local flag.
* @param keepBinary Keep binary flag.
* @return Initial iteration cursor.
*/
@SuppressWarnings("unchecked")
private QueryCursor<Cache.Entry<K, V>> queryContinuous(AbstractContinuousQuery qry, boolean loc, boolean keepBinary) {
GridCacheContext<K, V> ctx = getContextSafe();
assert qry instanceof ContinuousQuery || qry instanceof ContinuousQueryWithTransformer;
if (qry.getInitialQuery() instanceof ContinuousQuery || qry.getInitialQuery() instanceof ContinuousQueryWithTransformer) {
throw new IgniteException("Initial predicate for continuous query can't be an instance of another " + "continuous query. Use SCAN or SQL query for initial iteration.");
}
CacheEntryUpdatedListener locLsnr = null;
EventListener locTransLsnr = null;
CacheEntryEventSerializableFilter rmtFilter = null;
Factory<? extends IgniteClosure> rmtTransFactory = null;
if (qry instanceof ContinuousQuery) {
ContinuousQuery<K, V> qry0 = (ContinuousQuery<K, V>) qry;
if (qry0.getLocalListener() == null && qry0.getRemoteFilterFactory() == null && qry0.getRemoteFilter() == null) {
throw new IgniteException("LocalListener, RemoterFilter " + "or RemoteFilterFactory must be specified for the query: " + qry);
}
if (qry0.getRemoteFilter() != null && qry0.getRemoteFilterFactory() != null)
throw new IgniteException("Should be used either RemoterFilter or RemoteFilterFactory.");
locLsnr = qry0.getLocalListener();
rmtFilter = qry0.getRemoteFilter();
} else {
ContinuousQueryWithTransformer<K, V, ?> qry0 = (ContinuousQueryWithTransformer<K, V, ?>) qry;
if (qry0.getLocalListener() == null && qry0.getRemoteFilterFactory() == null) {
throw new IgniteException("LocalListener " + "or RemoteFilterFactory must be specified for the query: " + qry);
}
if (qry0.getRemoteTransformerFactory() == null)
throw new IgniteException("Mandatory RemoteTransformerFactory is not set for the query: " + qry);
Collection<ClusterNode> nodes = context().grid().cluster().nodes();
for (ClusterNode node : nodes) {
if (node.version().compareTo(CONT_QRY_WITH_TRANSFORMER_SINCE) < 0) {
throw new IgniteException("Can't start ContinuousQueryWithTransformer, " + "because some nodes in cluster doesn't support this feature: " + node);
}
}
locTransLsnr = qry0.getLocalListener();
rmtTransFactory = qry0.getRemoteTransformerFactory();
}
try {
final UUID routineId = ctx.continuousQueries().executeQuery(locLsnr, locTransLsnr, rmtFilter, qry.getRemoteFilterFactory(), rmtTransFactory, qry.getPageSize(), qry.getTimeInterval(), qry.isAutoUnsubscribe(), loc, keepBinary, qry.isIncludeExpired());
try {
final QueryCursor<Cache.Entry<K, V>> cur = qry.getInitialQuery() != null ? query(qry.getInitialQuery()) : null;
return new QueryCursorEx<Entry<K, V>>() {
@Override
public Iterator<Cache.Entry<K, V>> iterator() {
return cur != null ? cur.iterator() : new GridEmptyIterator<Cache.Entry<K, V>>();
}
@Override
public List<Cache.Entry<K, V>> getAll() {
return cur != null ? cur.getAll() : Collections.<Cache.Entry<K, V>>emptyList();
}
@Override
public void close() {
if (cur != null)
cur.close();
try {
ctx.kernalContext().continuous().stopRoutine(routineId).get();
} catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
@Override
public void getAll(Consumer<Entry<K, V>> c) {
// No-op.
}
@Override
public List<GridQueryFieldMetadata> fieldsMeta() {
// noinspection rawtypes
return cur instanceof QueryCursorEx ? ((QueryCursorEx) cur).fieldsMeta() : null;
}
};
} catch (Throwable t) {
// Initial query failed: stop the routine.
ctx.kernalContext().continuous().stopRoutine(routineId).get();
throw t;
}
} catch (IgniteCheckedException e) {
throw U.convertException(e);
}
}
use of org.apache.ignite.internal.processors.query.GridQueryFieldMetadata in project ignite by apache.
the class GridCacheQueryManager method runFieldsQuery.
/**
* Processes fields query request.
*
* @param qryInfo Query info.
*/
protected void runFieldsQuery(GridCacheQueryInfo qryInfo) {
assert qryInfo != null;
if (!enterBusy()) {
if (cctx.localNodeId().equals(qryInfo.senderId()))
throw new IllegalStateException("Failed to process query request (grid is stopping).");
// Ignore remote requests when when node is stopping.
return;
}
try {
if (log.isDebugEnabled())
log.debug("Running query: " + qryInfo);
boolean rmvRes = true;
FieldsResult res = null;
final boolean statsEnabled = cctx.statisticsEnabled();
final boolean readEvt = cctx.events().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
try {
// Preparing query closures.
IgniteReducer<Object, Object> rdc = (IgniteReducer<Object, Object>) qryInfo.reducer();
injectResources(rdc);
GridCacheQueryAdapter<?> qry = qryInfo.query();
int pageSize = qry.pageSize();
Collection<Object> data = null;
Collection<Object> entities = null;
if (qryInfo.local() || rdc != null || cctx.isLocalNode(qryInfo.senderId()))
data = new ArrayList<>(pageSize);
else
entities = new ArrayList<>(pageSize);
String taskName = cctx.kernalContext().task().resolveTaskName(qry.taskHash());
res = qryInfo.local() ? executeFieldsQuery(qry, qryInfo.arguments(), qryInfo.local(), taskName, recipient(qryInfo.senderId(), qryInfo.requestId())) : fieldsQueryResult(qryInfo, taskName);
// If metadata needs to be returned to user and cleaned from internal fields - copy it.
List<GridQueryFieldMetadata> meta = qryInfo.includeMetaData() ? (res.metaData() != null ? new ArrayList<>(res.metaData()) : null) : res.metaData();
if (!qryInfo.includeMetaData())
meta = null;
GridCloseableIterator<?> it = new GridSpiCloseableIteratorWrapper<Object>(res.iterator(recipient(qryInfo.senderId(), qryInfo.requestId())));
if (log.isDebugEnabled())
log.debug("Received fields iterator [iterHasNext=" + it.hasNext() + ']');
if (!it.hasNext()) {
if (rdc != null)
data = Collections.singletonList(rdc.reduce());
onFieldsPageReady(qryInfo.local(), qryInfo, meta, entities, data, true, null);
return;
}
int cnt = 0;
boolean metaSent = false;
while (!Thread.currentThread().isInterrupted() && it.hasNext()) {
long start = statsEnabled ? System.nanoTime() : 0L;
Object row = it.next();
// Query is cancelled.
if (row == null) {
onPageReady(qryInfo.local(), qryInfo, null, null, true, null);
break;
}
if (statsEnabled) {
CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.onRead(true);
metrics.addGetTimeNanos(System.nanoTime() - start);
}
if (readEvt && cctx.gridEvents().hasListener(EVT_CACHE_QUERY_OBJECT_READ)) {
cctx.gridEvents().record(new CacheQueryReadEvent<K, V>(cctx.localNode(), "SQL fields query result set row read.", EVT_CACHE_QUERY_OBJECT_READ, CacheQueryType.SQL_FIELDS.name(), cctx.name(), null, qry.clause(), null, null, qryInfo.arguments(), securitySubjectId(cctx), taskName, null, null, null, row));
}
if ((qryInfo.local() || rdc != null || cctx.isLocalNode(qryInfo.senderId()))) {
// Reduce.
if (rdc != null) {
if (!rdc.collect(row))
break;
} else
data.add(row);
} else
entities.add(row);
if (rdc == null && ((!qryInfo.allPages() && ++cnt == pageSize) || !it.hasNext())) {
onFieldsPageReady(qryInfo.local(), qryInfo, !metaSent ? meta : null, entities, data, !it.hasNext(), null);
if (it.hasNext())
rmvRes = false;
if (!qryInfo.allPages())
return;
}
}
if (rdc != null) {
onFieldsPageReady(qryInfo.local(), qryInfo, meta, null, Collections.singletonList(rdc.reduce()), true, null);
}
} catch (IgniteCheckedException e) {
if (log.isDebugEnabled() || !e.hasCause(SQLException.class))
U.error(log, "Failed to run fields query [qry=" + qryInfo + ", node=" + cctx.nodeId() + ']', e);
else {
if (e.hasCause(SQLException.class))
U.error(log, "Failed to run fields query [node=" + cctx.nodeId() + ", msg=" + e.getCause(SQLException.class).getMessage() + ']');
else
U.error(log, "Failed to run fields query [node=" + cctx.nodeId() + ", msg=" + e.getMessage() + ']');
}
onFieldsPageReady(qryInfo.local(), qryInfo, null, null, null, true, e);
} catch (Throwable e) {
U.error(log, "Failed to run fields query [qry=" + qryInfo + ", node=" + cctx.nodeId() + "]", e);
onFieldsPageReady(qryInfo.local(), qryInfo, null, null, null, true, e);
if (e instanceof Error)
throw (Error) e;
} finally {
if (qryInfo.local()) {
// Don't we need to always remove local iterators?
if (rmvRes && res != null) {
try {
res.closeIfNotShared(recipient(qryInfo.senderId(), qryInfo.requestId()));
} catch (IgniteCheckedException e) {
U.error(log, "Failed to close local iterator [qry=" + qryInfo + ", node=" + cctx.nodeId() + "]", e);
}
}
} else if (rmvRes)
removeFieldsQueryResult(qryInfo.senderId(), qryInfo.requestId());
}
} finally {
leaveBusy();
}
}
use of org.apache.ignite.internal.processors.query.GridQueryFieldMetadata in project ignite by apache.
the class PlatformFieldsQueryCursor method processOutStream.
/**
* {@inheritDoc}
*/
@Override
public void processOutStream(int type, final BinaryRawWriterEx writer) throws IgniteCheckedException {
if (type == OP_GET_FIELD_NAMES) {
List<GridQueryFieldMetadata> fieldsMeta = cursor().fieldsMeta();
writer.writeInt(fieldsMeta.size());
for (GridQueryFieldMetadata meta : fieldsMeta) writer.writeString(meta.fieldName());
} else if (type == OP_GET_FIELDS_META) {
List<GridQueryFieldMetadata> metas = cursor().fieldsMeta();
if (metas == null) {
writer.writeInt(0);
} else {
writer.writeInt(metas.size());
for (GridQueryFieldMetadata meta : metas) {
writer.writeString(meta.fieldName());
writer.writeString(meta.fieldTypeName());
}
}
} else {
super.processOutStream(type, writer);
}
}
use of org.apache.ignite.internal.processors.query.GridQueryFieldMetadata in project ignite by apache.
the class JdbcQueryTask method call.
/**
* {@inheritDoc}
*/
@Override
public JdbcQueryTaskResult call() throws Exception {
Cursor cursor = CURSORS.get(uuid);
List<String> tbls = null;
List<String> cols = null;
List<String> types = null;
boolean first;
if (first = (cursor == null)) {
IgniteCache<?, ?> cache = ignite.cache(cacheName);
// Don't create caches on server nodes in order to avoid of data rebalancing.
boolean start = ignite.configuration().isClientMode();
if (cache == null && cacheName == null)
cache = ((IgniteKernal) ignite).context().cache().getOrStartPublicCache(start, !loc && locQry);
if (cache == null) {
if (cacheName == null)
throw new SQLException("Failed to execute query. No suitable caches found.");
else
throw new SQLException("Cache not found [cacheName=" + cacheName + ']');
}
SqlFieldsQuery qry = (isQry != null ? new SqlFieldsQueryEx(sql, isQry) : new SqlFieldsQuery(sql)).setArgs(args);
qry.setPageSize(fetchSize);
qry.setLocal(locQry);
qry.setCollocated(collocatedQry);
qry.setDistributedJoins(distributedJoins);
qry.setEnforceJoinOrder(enforceJoinOrder());
qry.setLazy(lazy());
qry.setSchema(schemaName);
FieldsQueryCursor<List<?>> fldQryCursor = cache.withKeepBinary().query(qry);
if (fldQryCursor instanceof BulkLoadContextCursor) {
fldQryCursor.close();
throw new SQLException("COPY command is currently supported only in thin JDBC driver.");
}
QueryCursorImpl<List<?>> qryCursor = (QueryCursorImpl<List<?>>) fldQryCursor;
if (isQry == null)
isQry = qryCursor.isQuery();
CURSORS.put(uuid, cursor = new Cursor(qryCursor, qryCursor.iterator()));
}
if (first || updateMetadata()) {
Collection<GridQueryFieldMetadata> meta = cursor.queryCursor().fieldsMeta();
tbls = new ArrayList<>(meta.size());
cols = new ArrayList<>(meta.size());
types = new ArrayList<>(meta.size());
for (GridQueryFieldMetadata desc : meta) {
tbls.add(desc.typeName());
cols.add(desc.fieldName().toUpperCase());
types.add(desc.fieldTypeName());
}
}
List<List<?>> rows = new ArrayList<>();
for (List<?> row : cursor) {
List<Object> row0 = new ArrayList<>(row.size());
for (Object val : row) row0.add(val == null || JdbcUtils.isSqlType(val.getClass()) ? val : val.toString());
rows.add(row0);
if (// If fetchSize is 0 then unlimited
rows.size() == fetchSize)
break;
}
boolean finished = !cursor.hasNext();
if (finished)
remove(uuid, cursor);
else if (first) {
if (!loc)
scheduleRemoval(uuid);
} else if (!loc && !CURSORS.replace(uuid, cursor, new Cursor(cursor.cursor, cursor.iter)))
assert !CURSORS.containsKey(uuid) : "Concurrent cursor modification.";
assert isQry != null : "Query flag must be set prior to returning result";
return new JdbcQueryTaskResult(uuid, finished, isQry, rows, cols, tbls, types);
}
use of org.apache.ignite.internal.processors.query.GridQueryFieldMetadata in project ignite by apache.
the class H2Utils method meta.
/**
* @param rsMeta Metadata.
* @return List of fields metadata.
* @throws SQLException If failed.
*/
public static List<GridQueryFieldMetadata> meta(ResultSetMetaData rsMeta) throws SQLException {
List<GridQueryFieldMetadata> meta = new ArrayList<>(rsMeta.getColumnCount());
for (int i = 1; i <= rsMeta.getColumnCount(); i++) {
String schemaName = rsMeta.getSchemaName(i);
String typeName = rsMeta.getTableName(i);
String name = rsMeta.getColumnLabel(i);
String type = rsMeta.getColumnClassName(i);
int precision = rsMeta.getPrecision(i);
int scale = rsMeta.getScale(i);
int nullability = rsMeta.isNullable(i);
if (// Expression always returns NULL.
type == null)
type = Void.class.getName();
meta.add(new H2SqlFieldMetadata(schemaName, typeName, name, type, precision, scale, nullability));
}
return meta;
}
Aggregations