use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class GridQueryProcessor method dynamicTableCreate.
/**
* Create cache and table from given query entity.
*
* @param schemaName Schema name to create table in. Case sensitive, must not be \"quoted\".
* @param entity Entity to create table from.
* @param templateName Template name.
* @param cacheName Cache name.
* @param cacheGroup Cache group name.
* @param dataRegion Data region name.
* @param affinityKey Affinity key column name.
* @param atomicityMode Atomicity mode.
* @param writeSyncMode Write synchronization mode.
* @param backups Backups.
* @param ifNotExists Quietly ignore this command if table already exists.
* @param encrypted Encrypted flag.
* @param qryParallelism query parallelism value for configuration of underlying cache.
* @throws IgniteCheckedException If failed.
*/
public void dynamicTableCreate(String schemaName, QueryEntity entity, String templateName, String cacheName, String cacheGroup, @Nullable String dataRegion, String affinityKey, @Nullable CacheAtomicityMode atomicityMode, @Nullable CacheWriteSynchronizationMode writeSyncMode, @Nullable Integer backups, boolean ifNotExists, @Nullable Boolean encrypted, @Nullable Integer qryParallelism) throws IgniteCheckedException {
assert !F.isEmpty(templateName);
assert backups == null || backups >= 0;
assert qryParallelism == null || qryParallelism > 0;
CacheConfiguration<?, ?> ccfg = ctx.cache().getConfigFromTemplate(templateName);
if (ccfg == null) {
if (QueryUtils.TEMPLATE_PARTITIONED.equalsIgnoreCase(templateName))
ccfg = new CacheConfiguration<>().setCacheMode(CacheMode.PARTITIONED);
else if (QueryUtils.TEMPLATE_REPLICATED.equalsIgnoreCase(templateName))
ccfg = new CacheConfiguration<>().setCacheMode(CacheMode.REPLICATED);
else
throw new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, templateName);
ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
}
if (!F.isEmpty(ccfg.getQueryEntities()))
throw new SchemaOperationException("Template cache already contains query entities which it should not: " + templateName);
if (!F.isEmpty(entity.getNotNullFields()))
QueryUtils.checkNotNullAllowed(ccfg);
if (F.isEmpty(cacheName))
cacheName = QueryUtils.createTableCacheName(schemaName, entity.getTableName());
ccfg.setName(cacheName);
if (!F.isEmpty(cacheGroup))
ccfg.setGroupName(cacheGroup);
if (!F.isEmpty(dataRegion))
ccfg.setDataRegionName(dataRegion);
if (atomicityMode != null)
ccfg.setAtomicityMode(atomicityMode);
if (writeSyncMode != null)
ccfg.setWriteSynchronizationMode(writeSyncMode);
if (backups != null)
ccfg.setBackups(backups);
if (qryParallelism != null)
ccfg.setQueryParallelism(qryParallelism);
if (encrypted != null)
ccfg.setEncryptionEnabled(encrypted);
ccfg.setSqlSchema("\"" + schemaName + "\"");
ccfg.setSqlEscapeAll(true);
ccfg.setQueryEntities(Collections.singleton(entity));
if (!QueryUtils.isCustomAffinityMapper(ccfg.getAffinityMapper()))
ccfg.setAffinityMapper(null);
if (affinityKey != null)
ccfg.setKeyConfiguration(new CacheKeyConfiguration(entity.getKeyType(), affinityKey));
boolean res;
try {
res = ctx.grid().getOrCreateCache0(ccfg, true).get2();
} catch (CacheException e) {
if (e.getCause() instanceof SchemaOperationException)
throw (SchemaOperationException) e.getCause();
else
throw e;
}
if (!res && !ifNotExists)
throw new SchemaOperationException(SchemaOperationException.CODE_TABLE_EXISTS, entity.getTableName());
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException 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.schema.SchemaOperationException in project ignite by apache.
the class DynamicIndexAbstractConcurrentSelfTest method testConcurrentOperationsAndNodeStartStopMultithreaded.
/**
* Test concurrent node start/stop along with index operations. Nothing should hang.
*
* @throws Exception If failed.
*/
@Test
public void testConcurrentOperationsAndNodeStartStopMultithreaded() throws Exception {
// Start several stable nodes.
ignitionStart(serverConfiguration(1));
ignitionStart(serverConfiguration(2));
ignitionStart(serverConfiguration(3, true));
final Ignite cli = ignitionStart(clientConfiguration(4));
createSqlCache(cli);
final AtomicBoolean stopped = new AtomicBoolean();
// Start node start/stop worker.
final AtomicInteger nodeIdx = new AtomicInteger(4);
IgniteInternalFuture startStopFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
boolean exists = false;
int lastIdx = 0;
while (!stopped.get()) {
if (exists) {
stopGrid(lastIdx);
exists = false;
} else {
lastIdx = nodeIdx.incrementAndGet();
IgniteConfiguration cfg;
switch(ThreadLocalRandom.current().nextInt(0, 3)) {
case 1:
cfg = serverConfiguration(lastIdx, false);
break;
case 2:
cfg = serverConfiguration(lastIdx, true);
break;
default:
cfg = clientConfiguration(lastIdx);
}
ignitionStart(cfg);
exists = true;
}
Thread.sleep(ThreadLocalRandom.current().nextLong(500L, 1500L));
}
return null;
}
}, 1);
// Start several threads which will mess around indexes.
final QueryIndex idx = index(IDX_NAME_1, field(FIELD_NAME_1));
IgniteInternalFuture idxFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
boolean exists = false;
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
IgniteInternalFuture fut;
if (exists) {
fut = queryProcessor(node).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true);
exists = false;
} else {
fut = queryProcessor(node).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true, 0);
exists = true;
}
try {
fut.get();
} catch (SchemaOperationException e) {
// No-op.
} catch (Exception e) {
fail("Unexpected exception: " + e);
}
}
return null;
}
}, 1);
Thread.sleep(TEST_DUR);
stopped.set(true);
// Make sure nothing hanged.
startStopFut.get();
idxFut.get();
// Make sure cache is operational at this point.
createSqlCache(cli);
queryProcessor(cli).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true).get();
queryProcessor(cli).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true, 0).get();
assertIndex(CACHE_NAME, TBL_NAME, IDX_NAME_1, QueryIndex.DFLT_INLINE_SIZE, field(FIELD_NAME_1));
put(cli, 0, KEY_AFTER);
assertIndexUsed(IDX_NAME_1, SQL_SIMPLE_FIELD_1, SQL_ARG_1);
assertSqlSimpleData(SQL_SIMPLE_FIELD_1, KEY_AFTER - SQL_ARG_1);
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class DynamicIndexAbstractConcurrentSelfTest method testConcurrentOperationsMultithreaded.
/**
* Make sure that contended operations on the same index from different nodes do not hang.
*
* @throws Exception If failed.
*/
@Test
public void testConcurrentOperationsMultithreaded() throws Exception {
// Start complex topology.
ignitionStart(serverConfiguration(1));
ignitionStart(serverConfiguration(2));
ignitionStart(serverConfiguration(3, true));
Ignite cli = ignitionStart(clientConfiguration(4));
createSqlCache(cli);
final AtomicBoolean stopped = new AtomicBoolean();
// Start several threads which will mess around indexes.
final QueryIndex idx = index(IDX_NAME_1, field(FIELD_NAME_1));
IgniteInternalFuture idxFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
boolean exists = false;
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
IgniteInternalFuture fut;
if (exists) {
fut = queryProcessor(node).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true);
exists = false;
} else {
fut = queryProcessor(node).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true, 0);
exists = true;
}
try {
fut.get();
} catch (SchemaOperationException e) {
// No-op.
} catch (Exception e) {
fail("Unexpected exception: " + e);
}
}
return null;
}
}, 8);
Thread.sleep(TEST_DUR);
stopped.set(true);
// Make sure nothing hanged.
idxFut.get();
queryProcessor(cli).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true).get();
queryProcessor(cli).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true, 0).get();
assertIndex(CACHE_NAME, TBL_NAME, IDX_NAME_1, QueryIndex.DFLT_INLINE_SIZE, field(FIELD_NAME_1));
put(cli, 0, KEY_AFTER);
assertIndexUsed(IDX_NAME_1, SQL_SIMPLE_FIELD_1, SQL_ARG_1);
assertSqlSimpleData(SQL_SIMPLE_FIELD_1, KEY_AFTER - SQL_ARG_1);
}
use of org.apache.ignite.internal.processors.query.schema.SchemaOperationException in project ignite by apache.
the class DynamicIndexAbstractConcurrentSelfTest method testQueryConsistencyMultithreaded.
/**
* Make sure that contended operations on the same index from different nodes do not hang when we issue both
* CREATE/DROP and SELECT statements.
*
* @throws Exception If failed.
*/
@Test
public void testQueryConsistencyMultithreaded() throws Exception {
// Start complex topology.
ignitionStart(serverConfiguration(1));
ignitionStart(serverConfiguration(2));
ignitionStart(serverConfiguration(3, true));
Ignite cli = ignitionStart(clientConfiguration(4));
createSqlCache(cli);
put(cli, 0, KEY_AFTER);
final AtomicBoolean stopped = new AtomicBoolean();
// Thread which will mess around indexes.
final QueryIndex idx = index(IDX_NAME_1, field(FIELD_NAME_1));
IgniteInternalFuture idxFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
boolean exists = false;
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
IgniteInternalFuture fut;
if (exists) {
fut = queryProcessor(node).dynamicIndexDrop(CACHE_NAME, CACHE_NAME, IDX_NAME_1, true);
exists = false;
} else {
fut = queryProcessor(node).dynamicIndexCreate(CACHE_NAME, CACHE_NAME, TBL_NAME, idx, true, 0);
exists = true;
}
try {
fut.get();
} catch (SchemaOperationException e) {
// No-op.
} catch (Exception e) {
fail("Unexpected exception: " + e);
}
}
return null;
}
}, 1);
IgniteInternalFuture qryFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
try {
assertSqlSimpleData(node, SQL_SIMPLE_FIELD_1, KEY_AFTER - SQL_ARG_1);
} catch (Exception e) {
awaitConcDestroyException(e);
}
}
return null;
}
}, 8);
Thread.sleep(TEST_DUR);
stopped.set(true);
// Make sure nothing hanged.
idxFut.get();
qryFut.get();
}
Aggregations