use of org.apache.ignite.internal.processors.cache.QueryCursorImpl in project ignite by apache.
the class DmlStatementsProcessor method executeUpdateStatement.
/**
* Actually perform SQL DML operation locally.
*
* @param schemaName Schema name.
* @param cctx Cache context.
* @param c Connection.
* @param prepared Prepared statement for DML query.
* @param fieldsQry Fields query.
* @param loc Local query flag.
* @param filters Cache name and key filter.
* @param cancel Query cancel state holder.
* @return Pair [number of successfully processed items; keys that have failed to be processed]
* @throws IgniteCheckedException if failed.
*/
@SuppressWarnings({ "ConstantConditions", "unchecked" })
private UpdateResult executeUpdateStatement(String schemaName, final GridCacheContext cctx, Connection c, Prepared prepared, SqlFieldsQuery fieldsQry, boolean loc, IndexingQueryFilter filters, GridQueryCancel cancel) throws IgniteCheckedException {
Integer errKeysPos = null;
UpdatePlan plan = getPlanForStatement(schemaName, c, prepared, fieldsQry, loc, errKeysPos);
UpdateResult fastUpdateRes = plan.processFast(fieldsQry.getArgs());
if (fastUpdateRes != null)
return fastUpdateRes;
if (plan.distributedPlan() != null) {
UpdateResult result = doDistributedUpdate(schemaName, fieldsQry, plan, cancel);
// null is returned in case not all nodes support distributed DML.
if (result != null)
return result;
}
Iterable<List<?>> cur;
// sub-query and not some dummy stuff like "select 1, 2, 3;"
if (!loc && !plan.isLocalSubquery()) {
assert !F.isEmpty(plan.selectQuery());
SqlFieldsQuery newFieldsQry = new SqlFieldsQuery(plan.selectQuery(), fieldsQry.isCollocated()).setArgs(fieldsQry.getArgs()).setDistributedJoins(fieldsQry.isDistributedJoins()).setEnforceJoinOrder(fieldsQry.isEnforceJoinOrder()).setLocal(fieldsQry.isLocal()).setPageSize(fieldsQry.getPageSize()).setTimeout(fieldsQry.getTimeout(), TimeUnit.MILLISECONDS);
cur = (QueryCursorImpl<List<?>>) idx.querySqlFields(schemaName, newFieldsQry, null, true, true, cancel).get(0);
} else if (plan.hasRows())
cur = plan.createRows(fieldsQry.getArgs());
else {
final GridQueryFieldsResult res = idx.queryLocalSqlFields(schemaName, plan.selectQuery(), F.asList(fieldsQry.getArgs()), filters, fieldsQry.isEnforceJoinOrder(), fieldsQry.getTimeout(), cancel);
cur = new QueryCursorImpl<>(new Iterable<List<?>>() {
@Override
public Iterator<List<?>> iterator() {
try {
return new GridQueryCacheObjectsIterator(res.iterator(), idx.objectContext(), true);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
}, cancel);
}
int pageSize = loc ? 0 : fieldsQry.getPageSize();
return processDmlSelectResult(cctx, plan, cur, pageSize);
}
use of org.apache.ignite.internal.processors.cache.QueryCursorImpl in project ignite by apache.
the class IgniteH2Indexing method queryDistributedSql.
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry, boolean keepBinary, int mainCacheId) {
String type = qry.getType();
H2TableDescriptor tblDesc = tableDescriptor(schemaName, type);
if (tblDesc == null)
throw new IgniteSQLException("Failed to find SQL table for type: " + type, IgniteQueryErrorCode.TABLE_NOT_FOUND);
String sql;
try {
sql = generateQuery(qry.getSql(), qry.getAlias(), tblDesc);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
SqlFieldsQuery fqry = new SqlFieldsQuery(sql);
fqry.setArgs(qry.getArgs());
fqry.setPageSize(qry.getPageSize());
fqry.setDistributedJoins(qry.isDistributedJoins());
fqry.setPartitions(qry.getPartitions());
fqry.setLocal(qry.isLocal());
if (qry.getTimeout() > 0)
fqry.setTimeout(qry.getTimeout(), TimeUnit.MILLISECONDS);
final QueryCursor<List<?>> res = queryDistributedSqlFields(schemaName, fqry, keepBinary, null, mainCacheId);
final Iterable<Cache.Entry<K, V>> converted = new Iterable<Cache.Entry<K, V>>() {
@Override
public Iterator<Cache.Entry<K, V>> iterator() {
final Iterator<List<?>> iter0 = res.iterator();
return new Iterator<Cache.Entry<K, V>>() {
@Override
public boolean hasNext() {
return iter0.hasNext();
}
@Override
public Cache.Entry<K, V> next() {
List<?> l = iter0.next();
return new CacheEntryImpl<>((K) l.get(0), (V) l.get(1));
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
// No metadata for SQL queries.
return new QueryCursorImpl<Cache.Entry<K, V>>(converted) {
@Override
public void close() {
res.close();
}
};
}
use of org.apache.ignite.internal.processors.cache.QueryCursorImpl in project ignite by apache.
the class JdbcBatchUpdateTask method doSingleUpdate.
/**
* Performs update.
*
* @param cache Cache.
* @param sqlText SQL text.
* @param args Parameters.
* @return Update counter.
* @throws SQLException If failed.
*/
private Integer doSingleUpdate(IgniteCache<?, ?> cache, String sqlText, List<Object> args) throws SQLException {
SqlFieldsQuery qry = new SqlFieldsQueryEx(sqlText, false);
qry.setPageSize(fetchSize);
qry.setLocal(locQry);
qry.setCollocated(collocatedQry);
qry.setDistributedJoins(distributedJoins);
qry.setSchema(schemaName);
qry.setArgs(args == null ? null : args.toArray());
QueryCursorImpl<List<?>> qryCursor = (QueryCursorImpl<List<?>>) cache.withKeepBinary().query(qry);
if (qryCursor.isQuery()) {
throw createJdbcSqlException(getError("Query produced result set", qry), IgniteQueryErrorCode.STMT_TYPE_MISMATCH);
}
List<List<?>> rows = qryCursor.getAll();
if (F.isEmpty(rows))
return SUCCESS_NO_INFO;
if (rows.size() != 1)
throw new SQLException(getError("Expected single row for update operation result", qry));
List<?> row = rows.get(0);
if (F.isEmpty(row) || row.size() != 1)
throw new SQLException(getError("Expected row size of 1 for update operation", qry));
Object objRes = row.get(0);
if (!(objRes instanceof Long))
throw new SQLException(getError("Unexpected update result type", qry));
Long longRes = (Long) objRes;
if (longRes > Integer.MAX_VALUE) {
IgniteLogger log = ignite.log();
if (log != null)
log.warning(getError("Query updated row counter (" + longRes + ") exceeds integer range", qry));
return Integer.MAX_VALUE;
}
return longRes.intValue();
}
use of org.apache.ignite.internal.processors.cache.QueryCursorImpl in project ignite by apache.
the class JdbcQueryMultipleStatementsTask method call.
/**
* {@inheritDoc}
*/
@Override
public List<JdbcStatementResultInfo> call() throws Exception {
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);
GridKernalContext ctx = ((IgniteKernal) ignite).context();
List<FieldsQueryCursor<List<?>>> curs = ctx.query().querySqlFields(qry, true, false);
List<JdbcStatementResultInfo> resultsInfo = new ArrayList<>(curs.size());
for (FieldsQueryCursor<List<?>> cur0 : curs) {
QueryCursorImpl<List<?>> cur = (QueryCursorImpl<List<?>>) cur0;
long updCnt = -1;
UUID qryId = null;
if (!cur.isQuery()) {
List<List<?>> items = cur.getAll();
assert items != null && items.size() == 1 && items.get(0).size() == 1 && items.get(0).get(0) instanceof Long : "Invalid result set for not-SELECT query. [qry=" + sql + ", res=" + S.toString(List.class, items) + ']';
updCnt = (Long) items.get(0).get(0);
cur.close();
} else {
qryId = UUID.randomUUID();
JdbcQueryTask.Cursor jdbcCur = new JdbcQueryTask.Cursor(cur, cur.iterator());
JdbcQueryTask.addCursor(qryId, jdbcCur);
if (!loc)
JdbcQueryTask.scheduleRemoval(qryId);
}
JdbcStatementResultInfo resInfo = new JdbcStatementResultInfo(cur.isQuery(), qryId, updCnt);
resultsInfo.add(resInfo);
}
return resultsInfo;
}
use of org.apache.ignite.internal.processors.cache.QueryCursorImpl 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);
}
Aggregations