use of org.apache.ignite.internal.processors.query.QueryField in project ignite by apache.
the class GridH2Table method addColumns.
/**
* Add new columns to this table.
*
* @param cols Columns to add.
* @param ifNotExists Ignore this command if {@code cols} has size of 1 and column with given name already exists.
*/
public void addColumns(List<QueryField> cols, boolean ifNotExists) {
assert !ifNotExists || cols.size() == 1;
lock(true);
try {
Column[] safeColumns0 = safeColumns;
int pos = safeColumns0.length;
Column[] newCols = new Column[safeColumns0.length + cols.size()];
// First, let's copy existing columns to new array
System.arraycopy(safeColumns0, 0, newCols, 0, safeColumns0.length);
// And now, let's add new columns
for (QueryField col : cols) {
if (doesColumnExist(col.name())) {
if (ifNotExists && cols.size() == 1)
return;
else
throw new IgniteSQLException("Column already exists [tblName=" + getName() + ", colName=" + col.name() + ']');
}
try {
Column c = new Column(col.name(), DataType.getTypeFromClass(Class.forName(col.typeName())));
c.setNullable(col.isNullable());
newCols[pos++] = c;
} catch (ClassNotFoundException e) {
throw new IgniteSQLException("H2 data type not found for class: " + col.typeName(), e);
}
}
setColumns(newCols);
desc.refreshMetadataFromTypeDescriptor();
incrementModificationCounter();
} finally {
unlock(true);
}
}
use of org.apache.ignite.internal.processors.query.QueryField in project ignite by apache.
the class DynamicColumnsAbstractTest method getColumnMeta.
/**
* Checks presence of specific table column and returns it.
*
* @param node Node to check.
* @param schemaName Schema name to look for the table in.
* @param tblName Table name to check.
* @param colName Column name whose presence must be checked.
* @return field or {@code null} if not found.
* @throws SQLException if failed.
*/
static QueryField getColumnMeta(IgniteEx node, String schemaName, String tblName, String colName) throws SQLException {
try (Connection c = connect(node)) {
try (ResultSet rs = c.getMetaData().getColumns(null, schemaName, tblName, colName)) {
while (rs.next()) {
String name = rs.getString("COLUMN_NAME");
short type = rs.getShort("DATA_TYPE");
String typeClsName = DataType.getTypeClassName(DataType.convertSQLTypeToValueType(type));
short nullable = rs.getShort("NULLABLE");
return new QueryField(name, typeClsName, nullable == 1);
}
}
}
return null;
}
use of org.apache.ignite.internal.processors.query.QueryField in project ignite by apache.
the class DynamicColumnsAbstractConcurrentSelfTest method testOperationChaining.
/**
* Test operations join.
*
* @throws Exception If failed.
*/
@Test
public void testOperationChaining() throws Exception {
// 7 nodes * 2 columns = 14 latch countdowns.
CountDownLatch finishLatch = new CountDownLatch(14);
IgniteEx srv1 = ignitionStart(serverConfiguration(1), finishLatch);
ignitionStart(serverConfiguration(2), finishLatch);
ignitionStart(serverConfiguration(3, true), finishLatch);
ignitionStart(clientConfiguration(4), finishLatch);
createSqlCache(srv1);
run(srv1, createSql);
CountDownLatch idxLatch = blockIndexing(srv1);
QueryField c0 = c("ID", Integer.class.getName());
QueryField c1 = c("NAME", String.class.getName());
QueryField c2 = c("age", Integer.class.getName());
QueryField c3 = c("city", String.class.getName());
IgniteInternalFuture<?> colFut1 = addCols(srv1, QueryUtils.DFLT_SCHEMA, c2);
IgniteInternalFuture<?> colFut2 = dropCols(srv1, QueryUtils.DFLT_SCHEMA, c1.name());
IgniteInternalFuture<?> colFut3 = addCols(srv1, QueryUtils.DFLT_SCHEMA, c3);
U.await(idxLatch);
// Start even more nodes of different flavors
ignitionStart(serverConfiguration(5), finishLatch);
ignitionStart(serverConfiguration(6, true), finishLatch);
ignitionStart(clientConfiguration(7), finishLatch);
assert !colFut1.isDone();
assert !colFut2.isDone();
assert !colFut3.isDone();
unblockIndexing(srv1);
colFut1.get();
colFut2.get();
colFut3.get();
U.await(finishLatch);
checkTableState(srv1, QueryUtils.DFLT_SCHEMA, TBL_NAME, c0, c2, c3);
}
use of org.apache.ignite.internal.processors.query.QueryField in project ignite by apache.
the class DynamicColumnsAbstractConcurrentSelfTest method testConcurrentOperationsAndNodeStartStopMultithreaded.
/**
* Test concurrent node start/stop along with add/drop column operations. Nothing should hang.
*
* @throws Exception If failed.
*/
@SuppressWarnings("StringConcatenationInLoop")
@Test
public void testConcurrentOperationsAndNodeStartStopMultithreaded() throws Exception {
// Start several stable nodes.
ignitionStart(serverConfiguration(1));
ignitionStart(serverConfiguration(2));
ignitionStart(serverConfiguration(3, true));
final IgniteEx cli = ignitionStart(clientConfiguration(4));
createSqlCache(cli);
run(cli, createSql);
final AtomicBoolean stopped = new AtomicBoolean();
// Start node start/stop worker.
final AtomicInteger nodeIdx = new AtomicInteger(4);
final AtomicInteger dynColCnt = new AtomicInteger();
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);
final GridConcurrentHashSet<Integer> fields = new GridConcurrentHashSet<>();
IgniteInternalFuture idxFut = multithreadedAsync(new Callable<Void>() {
@Override
public Void call() throws Exception {
while (!stopped.get()) {
Ignite node = grid(ThreadLocalRandom.current().nextInt(1, 5));
IgniteInternalFuture fut;
int fieldNum = ThreadLocalRandom.current().nextInt(0, dynColCnt.get() + 1);
boolean removed = fields.remove(fieldNum);
if (removed)
fut = dropCols(node, QueryUtils.DFLT_SCHEMA, "newCol" + fieldNum);
else {
fieldNum = dynColCnt.getAndIncrement();
fut = addCols(node, QueryUtils.DFLT_SCHEMA, c("newCol" + fieldNum, Integer.class.getName()));
}
try {
fut.get();
if (!removed)
fields.add(fieldNum);
} 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);
QueryField[] expCols = new QueryField[fields.size()];
// Too many index columns kills indexing internals, have to limit number of the columns
// to build the index on.
int idxColsCnt = Math.min(300, expCols.length);
Integer[] args = new Integer[idxColsCnt];
String updQry = "UPDATE " + TBL_NAME + " SET ";
String idxQry = "CREATE INDEX idx ON " + TBL_NAME + '(';
Integer[] sorted = fields.toArray(new Integer[fields.size()]);
Arrays.sort(sorted);
for (int i = 0; i < expCols.length; i++) {
int fieldNum = sorted[i];
expCols[i] = c("newCol" + fieldNum, Integer.class.getName());
if (i >= idxColsCnt)
continue;
if (i > 0) {
updQry += ", ";
idxQry += ", ";
}
updQry += "\"newCol" + fieldNum + "\" = id + ?";
idxQry += "\"newCol" + fieldNum + '"';
args[i] = i;
}
idxQry += ')';
checkTableState(cli, QueryUtils.DFLT_SCHEMA, TBL_NAME, expCols);
put(cli, 0, 500);
run(cli.cache(CACHE_NAME), updQry, (Object[]) args);
run(cli, idxQry);
run(cli, "DROP INDEX idx");
}
use of org.apache.ignite.internal.processors.query.QueryField in project ignite by apache.
the class DynamicColumnsAbstractConcurrentSelfTest method checkNodeJoinOnPendingOperation.
/**
* Check node join on pending operation.
*
* @param addOrRemove Pass {@code true} to check add column. Otherwise, drop column is checked.
* @throws Exception If failed.
*/
private void checkNodeJoinOnPendingOperation(boolean addOrRemove) throws Exception {
CountDownLatch finishLatch = new CountDownLatch(3);
IgniteEx srv1 = ignitionStart(serverConfiguration(1), finishLatch);
createSqlCache(srv1);
run(srv1, addOrRemove ? createSql : createSql4Cols);
CountDownLatch idxLatch = blockIndexing(srv1);
QueryField c = c("AGE", Integer.class.getName());
IgniteInternalFuture<?> idxFut = addOrRemove ? addCols(srv1, QueryUtils.DFLT_SCHEMA, c) : dropCols(srv1, QueryUtils.DFLT_SCHEMA, "CITY");
U.await(idxLatch);
ignitionStart(serverConfiguration(2), finishLatch);
ignitionStart(serverConfiguration(3, true), finishLatch);
assertFalse(idxFut.isDone());
unblockIndexing(srv1);
idxFut.get();
U.await(finishLatch);
checkTableState(srv1, QueryUtils.DFLT_SCHEMA, TBL_NAME, c);
}
Aggregations