Search in sources :

Example 1 with QueryField

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);
    }
}
Also used : QueryField(org.apache.ignite.internal.processors.query.QueryField) IndexColumn(org.h2.table.IndexColumn) Column(org.h2.table.Column) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 2 with QueryField

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;
}
Also used : QueryField(org.apache.ignite.internal.processors.query.QueryField) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet)

Example 3 with QueryField

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);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) QueryField(org.apache.ignite.internal.processors.query.QueryField) IgniteEx(org.apache.ignite.internal.IgniteEx) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test) IgniteClientReconnectAbstractTest(org.apache.ignite.internal.IgniteClientReconnectAbstractTest)

Example 4 with QueryField

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");
}
Also used : SchemaOperationException(org.apache.ignite.internal.processors.query.schema.SchemaOperationException) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) QueryRetryException(org.apache.ignite.cache.query.QueryRetryException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) SchemaOperationException(org.apache.ignite.internal.processors.query.schema.SchemaOperationException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) GridConcurrentHashSet(org.apache.ignite.internal.util.GridConcurrentHashSet) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) IgniteConfiguration(org.apache.ignite.configuration.IgniteConfiguration) QueryField(org.apache.ignite.internal.processors.query.QueryField) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IgniteEx(org.apache.ignite.internal.IgniteEx) Ignite(org.apache.ignite.Ignite) BinaryObject(org.apache.ignite.binary.BinaryObject) Test(org.junit.Test) IgniteClientReconnectAbstractTest(org.apache.ignite.internal.IgniteClientReconnectAbstractTest)

Example 5 with QueryField

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);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) QueryField(org.apache.ignite.internal.processors.query.QueryField) IgniteEx(org.apache.ignite.internal.IgniteEx) CountDownLatch(java.util.concurrent.CountDownLatch)

Aggregations

QueryField (org.apache.ignite.internal.processors.query.QueryField)21 Test (org.junit.Test)10 List (java.util.List)6 ArrayList (java.util.ArrayList)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 IgniteEx (org.apache.ignite.internal.IgniteEx)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 Ignite (org.apache.ignite.Ignite)4 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)4 BinaryObject (org.apache.ignite.binary.BinaryObject)4 SchemaOperationException (org.apache.ignite.internal.processors.query.schema.SchemaOperationException)4 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)3 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)3 Connection (java.sql.Connection)2 ResultSet (java.sql.ResultSet)2 IgniteException (org.apache.ignite.IgniteException)2 QueryEntity (org.apache.ignite.cache.QueryEntity)2