use of org.apache.ignite.internal.processors.query.h2.opt.GridH2Table in project ignite by apache.
the class CommandProcessor method runCommandH2.
/**
* Execute DDL statement.
*
* @param sql SQL.
* @param cmdH2 Command.
*/
private void runCommandH2(String sql, GridSqlStatement cmdH2) {
IgniteInternalFuture fut = null;
try {
finishActiveTxIfNecessary();
if (cmdH2 instanceof GridSqlCreateIndex) {
GridSqlCreateIndex cmd = (GridSqlCreateIndex) cmdH2;
isDdlOnSchemaSupported(cmd.schemaName());
GridH2Table tbl = schemaMgr.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null)
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName());
assert tbl.rowDescriptor() != null;
ensureDdlSupported(tbl);
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(), 0);
} else if (cmdH2 instanceof GridSqlDropIndex) {
GridSqlDropIndex cmd = (GridSqlDropIndex) cmdH2;
isDdlOnSchemaSupported(cmd.schemaName());
GridH2Table tbl = schemaMgr.dataTableForIndex(cmd.schemaName(), cmd.indexName());
if (tbl != null) {
ensureDdlSupported(tbl);
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 (cmdH2 instanceof GridSqlCreateTable) {
GridSqlCreateTable cmd = (GridSqlCreateTable) cmdH2;
ctx.security().authorize(cmd.cacheName(), SecurityPermission.CACHE_CREATE);
isDdlOnSchemaSupported(cmd.schemaName());
GridH2Table tbl = schemaMgr.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl != null) {
if (!cmd.ifNotExists())
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_EXISTS, cmd.tableName());
} else {
QueryEntity e = toQueryEntity(cmd);
CacheConfiguration<?, ?> ccfg = new CacheConfiguration<>(cmd.tableName());
ccfg.setQueryEntities(Collections.singleton(e));
ccfg.setSqlSchema(cmd.schemaName());
SchemaOperationException err = QueryUtils.checkQueryEntityConflicts(ccfg, ctx.cache().cacheDescriptors().values());
if (err != null)
throw err;
if (!F.isEmpty(cmd.cacheName()) && ctx.cache().cacheDescriptor(cmd.cacheName()) != null) {
ctx.query().dynamicAddQueryEntity(cmd.cacheName(), cmd.schemaName(), e, cmd.parallelism(), true).get();
} else {
ctx.query().dynamicTableCreate(cmd.schemaName(), e, cmd.templateName(), cmd.cacheName(), cmd.cacheGroup(), cmd.dataRegionName(), cmd.affinityKey(), cmd.atomicityMode(), cmd.writeSynchronizationMode(), cmd.backups(), cmd.ifNotExists(), cmd.encrypted(), cmd.parallelism());
}
}
} else if (cmdH2 instanceof GridSqlDropTable) {
GridSqlDropTable cmd = (GridSqlDropTable) cmdH2;
isDdlOnSchemaSupported(cmd.schemaName());
GridH2Table tbl = schemaMgr.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null) {
if (!cmd.ifExists())
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName());
} else {
ctx.security().authorize(tbl.cacheName(), SecurityPermission.CACHE_DESTROY);
ctx.query().dynamicTableDrop(tbl.cacheName(), cmd.tableName(), cmd.ifExists());
}
} else if (cmdH2 instanceof GridSqlAlterTableAddColumn) {
GridSqlAlterTableAddColumn cmd = (GridSqlAlterTableAddColumn) cmdH2;
isDdlOnSchemaSupported(cmd.schemaName());
GridH2Table tbl = schemaMgr.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null) {
if (!cmd.ifTableExists())
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName());
} else {
if (QueryUtils.isSqlType(tbl.rowDescriptor().type().valueClass()))
throw new SchemaOperationException("Cannot add column(s) because table was created " + "with " + PARAM_WRAP_VALUE + "=false option.");
List<QueryField> cols = new ArrayList<>(cmd.columns().length);
boolean allFieldsNullable = true;
for (GridSqlColumn col : cmd.columns()) {
if (tbl.doesColumnExist(col.columnName())) {
if ((!cmd.ifNotExists() || cmd.columns().length != 1)) {
throw new SchemaOperationException(SchemaOperationException.CODE_COLUMN_EXISTS, col.columnName());
} else {
cols = null;
break;
}
}
QueryField field = new QueryField(col.columnName(), getTypeClassName(col), col.column().isNullable(), col.defaultValue(), col.precision(), col.scale());
cols.add(field);
allFieldsNullable &= field.isNullable();
}
if (cols != null) {
assert tbl.rowDescriptor() != null;
if (!allFieldsNullable)
QueryUtils.checkNotNullAllowed(tbl.cacheInfo().config());
fut = ctx.query().dynamicColumnAdd(tbl.cacheName(), cmd.schemaName(), tbl.rowDescriptor().type().tableName(), cols, cmd.ifTableExists(), cmd.ifNotExists());
}
}
} else if (cmdH2 instanceof GridSqlAlterTableDropColumn) {
GridSqlAlterTableDropColumn cmd = (GridSqlAlterTableDropColumn) cmdH2;
isDdlOnSchemaSupported(cmd.schemaName());
GridH2Table tbl = schemaMgr.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null) {
if (!cmd.ifTableExists())
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_NOT_FOUND, cmd.tableName());
} else {
assert tbl.rowDescriptor() != null;
GridCacheContext cctx = tbl.cacheContext();
assert cctx != null;
if (cctx.mvccEnabled())
throw new IgniteSQLException("Cannot drop column(s) with enabled MVCC. " + "Operation is unsupported at the moment.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
if (QueryUtils.isSqlType(tbl.rowDescriptor().type().valueClass()))
throw new SchemaOperationException("Cannot drop column(s) because table was created " + "with " + PARAM_WRAP_VALUE + "=false option.");
List<String> cols = new ArrayList<>(cmd.columns().length);
GridQueryTypeDescriptor type = tbl.rowDescriptor().type();
for (String colName : cmd.columns()) {
if (!tbl.doesColumnExist(colName)) {
if ((!cmd.ifExists() || cmd.columns().length != 1)) {
throw new SchemaOperationException(SchemaOperationException.CODE_COLUMN_NOT_FOUND, colName);
} else {
cols = null;
break;
}
}
SchemaOperationException err = QueryUtils.validateDropColumn(type, colName);
if (err != null)
throw err;
cols.add(colName);
}
if (cols != null) {
fut = ctx.query().dynamicColumnRemove(tbl.cacheName(), cmd.schemaName(), type.tableName(), cols, cmd.ifTableExists(), cmd.ifExists());
}
}
} else
throw new IgniteSQLException("Unsupported DDL operation: " + sql, IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
if (fut != null)
fut.get();
} catch (SchemaOperationException e) {
U.error(null, "DDL operation failure", e);
throw convert(e);
} catch (IgniteSQLException e) {
throw e;
} catch (Exception e) {
throw new IgniteSQLException(e.getMessage(), e);
}
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2Table in project ignite by apache.
the class CommandProcessor method processBulkLoadCommand.
/**
* Process bulk load COPY command.
*
* @param cmd The command.
* @param qryId Query id.
* @return The context (which is the result of the first request/response).
* @throws IgniteCheckedException If something failed.
*/
private FieldsQueryCursor<List<?>> processBulkLoadCommand(SqlBulkLoadCommand cmd, long qryId) throws IgniteCheckedException {
if (cmd.packetSize() == null)
cmd.packetSize(BulkLoadAckClientParameters.DFLT_PACKET_SIZE);
GridH2Table tbl = schemaMgr.dataTable(cmd.schemaName(), cmd.tableName());
if (tbl == null) {
throw new IgniteSQLException("Table does not exist: " + cmd.tableName(), IgniteQueryErrorCode.TABLE_NOT_FOUND);
}
H2Utils.checkAndStartNotStartedCache(ctx, tbl);
UpdatePlan plan = UpdatePlanBuilder.planForBulkLoad(cmd, tbl);
IgniteClosureX<List<?>, IgniteBiTuple<?, ?>> dataConverter = new DmlBulkLoadDataConverter(plan);
IgniteDataStreamer<Object, Object> streamer = ctx.grid().dataStreamer(tbl.cacheName());
BulkLoadCacheWriter outputWriter = new BulkLoadStreamerWriter(streamer);
BulkLoadParser inputParser = BulkLoadParser.createParser(cmd.inputFormat());
BulkLoadProcessor processor = new BulkLoadProcessor(inputParser, dataConverter, outputWriter, idx.runningQueryManager(), qryId, ctx.tracing());
BulkLoadAckClientParameters params = new BulkLoadAckClientParameters(cmd.localFileName(), cmd.packetSize());
return new BulkLoadContextCursor(processor, params);
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2Table in project ignite by apache.
the class IgniteStatisticsConfigurationManager method updateLocalStatistics.
/**
* Pass all necessary parameters to schedule statistics key update.
*
* @param cfg Statistics object configuration to update statistics by.
*/
private void updateLocalStatistics(StatisticsObjectConfiguration cfg) {
GridH2Table tbl = schemaMgr.dataTable(cfg.key().schema(), cfg.key().obj());
if (tbl == null || cfg.columns().isEmpty()) {
// Can be drop table event, need to ensure that there is no stored data left for this table.
if (log.isDebugEnabled()) {
if (tbl == null)
log.debug("Can't find table by key " + cfg.key() + ". Check statistics empty.");
else if (cfg == null)
log.debug("Tombstone configuration by key " + cfg.key() + ". Check statistics empty.");
}
// Ensure to clean local metastorage.
LocalStatisticsGatheringContext ctx = new LocalStatisticsGatheringContext(false, tbl, cfg, Collections.emptySet(), topVer);
statProc.updateLocalStatistics(ctx);
if (tbl == null && !cfg.columns().isEmpty()) {
if (log.isDebugEnabled())
log.debug("Removing config for non existing object " + cfg.key());
dropStatistics(Collections.singletonList(new StatisticsTarget(cfg.key())), false);
}
return;
}
GridCacheContext<?, ?> cctx = tbl.cacheContext();
if (cctx == null || !cctx.gate().enterIfNotStopped()) {
if (log.isDebugEnabled())
log.debug("Unable to lock table by key " + cfg.key() + ". Skipping statistics collection.");
return;
}
try {
AffinityTopologyVersion topVer0 = cctx.affinity().affinityReadyFuture(topVer).get();
final Set<Integer> primParts = cctx.affinity().primaryPartitions(cctx.localNodeId(), topVer0);
LocalStatisticsGatheringContext ctx = new LocalStatisticsGatheringContext(false, tbl, cfg, primParts, topVer0);
statProc.updateLocalStatistics(ctx);
} catch (IgniteCheckedException e) {
log.warning("Unexpected error during statistics collection: " + e.getMessage(), e);
} finally {
cctx.gate().leave();
}
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2Table 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;
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2Table in project ignite by apache.
the class GridSqlQueryParser method parseSelect.
/**
* @param select Select.
*/
private GridSqlSelect parseSelect(Select select) {
GridSqlSelect res = (GridSqlSelect) h2ObjToGridObj.get(select);
if (res != null)
return res;
res = new GridSqlSelect();
h2ObjToGridObj.put(select, res);
res.distinct(select.isDistinct());
Expression where = CONDITION.get(select);
res.where(parseExpression(where, true));
ArrayList<TableFilter> tableFilters = new ArrayList<>();
TableFilter filter = select.getTopTableFilter();
boolean isForUpdate = SELECT_IS_FOR_UPDATE.get(select);
do {
assert0(filter != null, select);
assert0(filter.getNestedJoin() == null, select);
// Can use optimized join order only if we are not inside of an expression.
if (parsingSubQryExpression == 0 && optimizedTableFilterOrder != null) {
String tblAlias = filter.getTableAlias();
int idx = optimizedTableFilterOrder.get(tblAlias);
setElementAt(tableFilters, idx, filter);
} else
tableFilters.add(filter);
filter = filter.getJoin();
} while (filter != null);
// Build FROM clause from correctly ordered table filters.
GridSqlElement from = null;
for (int i = 0; i < tableFilters.size(); i++) {
TableFilter f = tableFilters.get(i);
GridSqlElement gridFilter = parseTableFilter(f);
from = from == null ? gridFilter : new GridSqlJoin(from, gridFilter, f.isJoinOuter(), parseExpression(f.getJoinCondition(), true));
}
res.from(from);
if (isForUpdate) {
if (!(from instanceof GridSqlTable || (from instanceof GridSqlAlias && from.size() == 1 && from.child() instanceof GridSqlTable))) {
throw new IgniteSQLException("SELECT FOR UPDATE with joins is not supported.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
GridSqlTable gridTbl = from instanceof GridSqlTable ? (GridSqlTable) from : ((GridSqlAlias) from).child();
GridH2Table tbl = gridTbl.dataTable();
if (tbl == null) {
throw new IgniteSQLException("SELECT FOR UPDATE query must involve Ignite table.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (select.getLimit() != null || select.getOffset() != null) {
throw new IgniteSQLException("LIMIT/OFFSET clauses are not supported for SELECT FOR UPDATE.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (SELECT_IS_GROUP_QUERY.get(select)) {
throw new IgniteSQLException("SELECT FOR UPDATE with aggregates and/or GROUP BY is not supported.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (select.isDistinct())
throw new IgniteSQLException("DISTINCT clause is not supported for SELECT FOR UPDATE.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
if (SplitterUtils.hasSubQueries(res))
throw new IgniteSQLException("Sub queries are not supported for SELECT FOR UPDATE.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
ArrayList<Expression> expressions = select.getExpressions();
for (int i = 0; i < expressions.size(); i++) res.addColumn(parseExpression(expressions.get(i), true), i < select.getColumnCount());
int[] grpIdx = GROUP_INDEXES.get(select);
if (grpIdx != null)
res.groupColumns(grpIdx);
int havingIdx = HAVING_INDEX.get(select);
if (havingIdx >= 0)
res.havingColumn(havingIdx);
res.forUpdate(isForUpdate);
processSortOrder(select.getSortOrder(), res);
res.limit(parseExpression(select.getLimit(), false));
res.offset(parseExpression(select.getOffset(), false));
return res;
}
Aggregations