Search in sources :

Example 21 with Schema

use of org.h2.schema.Schema in project ignite by apache.

the class IgniteH2Indexing method connectionForThread.

/**
 * Gets DB connection.
 *
 * @param schema Whether to set schema for connection or not.
 * @return DB connection.
 * @throws IgniteCheckedException In case of error.
 */
private Connection connectionForThread(@Nullable String schema) throws IgniteCheckedException {
    H2ConnectionWrapper c = connCache.get();
    if (c == null)
        throw new IgniteCheckedException("Failed to get DB connection for thread (check log for details).");
    if (schema != null && !F.eq(c.schema(), schema)) {
        Statement stmt = null;
        try {
            stmt = c.connection().createStatement();
            stmt.executeUpdate("SET SCHEMA " + H2Utils.withQuotes(schema));
            if (log.isDebugEnabled())
                log.debug("Set schema: " + schema);
            c.schema(schema);
        } catch (SQLException e) {
            throw new IgniteSQLException("Failed to set schema for DB connection for thread [schema=" + schema + "]", e);
        } finally {
            U.close(stmt, log);
        }
    }
    return c.connection();
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) PreparedStatement(java.sql.PreparedStatement) JdbcStatement(org.h2.jdbc.JdbcStatement) Statement(java.sql.Statement) GridSqlStatement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 22 with Schema

use of org.h2.schema.Schema in project ignite by apache.

the class IgniteH2Indexing method executeStatement.

/**
 * @param schema Schema
 * @param sql SQL statement.
 * @throws IgniteCheckedException If failed.
 */
public void executeStatement(String schema, String sql) throws IgniteCheckedException {
    Statement stmt = null;
    try {
        Connection c = connectionForThread(schema);
        stmt = c.createStatement();
        stmt.executeUpdate(sql);
    } catch (SQLException e) {
        onSqlException();
        throw new IgniteSQLException("Failed to execute statement: " + sql, e);
    } finally {
        U.close(stmt, log);
    }
}
Also used : SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) PreparedStatement(java.sql.PreparedStatement) JdbcStatement(org.h2.jdbc.JdbcStatement) Statement(java.sql.Statement) GridSqlStatement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement) Connection(java.sql.Connection) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 23 with Schema

use of org.h2.schema.Schema in project ignite by apache.

the class IgniteH2Indexing method parseAndSplit.

/**
 * Parse and split query if needed, cache either two-step query or statement.
 * @param schemaName Schema name.
 * @param qry Query.
 * @param firstArg Position of the first argument of the following {@code Prepared}.
 * @return Result: prepared statement, H2 command, two-step query (if needed),
 *     metadata for two-step query (if needed), evaluated query local execution flag.
 */
private ParsingResult parseAndSplit(String schemaName, SqlFieldsQuery qry, int firstArg) {
    Connection c = connectionForSchema(schemaName);
    // For queries that are explicitly local, we rely on the flag specified in the query
    // because this parsing result will be cached and used for queries directly.
    // For other queries, we enforce join order at this stage to avoid premature optimizations
    // (and therefore longer parsing) as long as there'll be more parsing at split stage.
    boolean enforceJoinOrderOnParsing = (!qry.isLocal() || qry.isEnforceJoinOrder());
    H2Utils.setupConnection(c, /*distributedJoins*/
    false, /*enforceJoinOrder*/
    enforceJoinOrderOnParsing);
    boolean loc = qry.isLocal();
    PreparedStatement stmt = prepareStatementAndCaches(c, qry.getSql());
    if (loc && GridSqlQueryParser.checkMultipleStatements(stmt))
        throw new IgniteSQLException("Multiple statements queries are not supported for local queries");
    GridSqlQueryParser.PreparedWithRemaining prep = GridSqlQueryParser.preparedWithRemaining(stmt);
    Prepared prepared = prep.prepared();
    checkQueryType(qry, prepared.isQuery());
    String remainingSql = prep.remainingSql();
    int paramsCnt = prepared.getParameters().size();
    Object[] argsOrig = qry.getArgs();
    Object[] args = null;
    if (!DmlUtils.isBatched(qry) && paramsCnt > 0) {
        if (argsOrig == null || argsOrig.length < firstArg + paramsCnt) {
            throw new IgniteException("Invalid number of query parameters. " + "Cannot find " + (argsOrig != null ? argsOrig.length + 1 - firstArg : 1) + " parameter.");
        }
        args = Arrays.copyOfRange(argsOrig, firstArg, firstArg + paramsCnt);
    }
    if (prepared.isQuery()) {
        try {
            bindParameters(stmt, F.asList(args));
        } catch (IgniteCheckedException e) {
            U.closeQuiet(stmt);
            throw new IgniteSQLException("Failed to bind parameters: [qry=" + prepared.getSQL() + ", params=" + Arrays.deepToString(args) + "]", IgniteQueryErrorCode.PARSING, e);
        }
        GridSqlQueryParser parser = null;
        if (!loc) {
            parser = new GridSqlQueryParser(false);
            GridSqlStatement parsedStmt = parser.parse(prepared);
            // Legit assertion - we have H2 query flag above.
            assert parsedStmt instanceof GridSqlQuery;
            loc = parser.isLocalQuery(qry.isReplicatedOnly());
        }
        if (loc) {
            if (parser == null) {
                parser = new GridSqlQueryParser(false);
                parser.parse(prepared);
            }
            GridCacheContext cctx = parser.getFirstPartitionedCache();
            if (cctx != null && cctx.config().getQueryParallelism() > 1) {
                loc = false;
                qry.setDistributedJoins(true);
            }
        }
    }
    SqlFieldsQuery newQry = cloneFieldsQuery(qry).setSql(prepared.getSQL()).setArgs(args);
    boolean hasTwoStep = !loc && prepared.isQuery();
    // Let's not cache multiple statements and distributed queries as whole two step query will be cached later on.
    if (remainingSql != null || hasTwoStep)
        getStatementsCacheForCurrentThread().remove(schemaName, qry.getSql());
    if (!hasTwoStep)
        return new ParsingResult(prepared, newQry, remainingSql, null, null, null);
    final UUID locNodeId = ctx.localNodeId();
    // Now we're sure to have a distributed query. Let's try to get a two-step plan from the cache, or perform the
    // split if needed.
    H2TwoStepCachedQueryKey cachedQryKey = new H2TwoStepCachedQueryKey(schemaName, qry.getSql(), qry.isCollocated(), qry.isDistributedJoins(), qry.isEnforceJoinOrder(), qry.isLocal());
    H2TwoStepCachedQuery cachedQry;
    if ((cachedQry = twoStepCache.get(cachedQryKey)) != null) {
        checkQueryType(qry, true);
        GridCacheTwoStepQuery twoStepQry = cachedQry.query().copy();
        List<GridQueryFieldMetadata> meta = cachedQry.meta();
        return new ParsingResult(prepared, newQry, remainingSql, twoStepQry, cachedQryKey, meta);
    }
    try {
        GridH2QueryContext.set(new GridH2QueryContext(locNodeId, locNodeId, 0, PREPARE).distributedJoinMode(distributedJoinMode(qry.isLocal(), qry.isDistributedJoins())));
        try {
            return new ParsingResult(prepared, newQry, remainingSql, split(prepared, newQry), cachedQryKey, H2Utils.meta(stmt.getMetaData()));
        } catch (IgniteCheckedException e) {
            throw new IgniteSQLException("Failed to bind parameters: [qry=" + newQry.getSql() + ", params=" + Arrays.deepToString(newQry.getArgs()) + "]", IgniteQueryErrorCode.PARSING, e);
        } catch (SQLException e) {
            throw new IgniteSQLException(e);
        } finally {
            U.close(stmt, log);
        }
    } finally {
        GridH2QueryContext.clearThreadLocal();
    }
}
Also used : SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlStatement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement) Prepared(org.h2.command.Prepared) GridCacheTwoStepQuery(org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery) GridQueryFieldMetadata(org.apache.ignite.internal.processors.query.GridQueryFieldMetadata) IgniteSystemProperties.getString(org.apache.ignite.IgniteSystemProperties.getString) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) UUID(java.util.UUID) GridH2QueryContext(org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) SqlFieldsQuery(org.apache.ignite.cache.query.SqlFieldsQuery) GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridSqlQueryParser(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 24 with Schema

use of org.h2.schema.Schema in project ignite by apache.

the class IgniteH2Indexing method queryLocalSqlFields.

/**
 * Queries individual fields (generally used by JDBC drivers).
 *
 * @param schemaName Schema name.
 * @param qry Query.
 * @param params Query parameters.
 * @param filter Cache name and key filter.
 * @param enforceJoinOrder Enforce join order of tables in the query.
 * @param timeout Query timeout in milliseconds.
 * @param cancel Query cancel.
 * @return Query result.
 * @throws IgniteCheckedException If failed.
 */
@SuppressWarnings("unchecked")
GridQueryFieldsResult queryLocalSqlFields(final String schemaName, final String qry, @Nullable final Collection<Object> params, final IndexingQueryFilter filter, boolean enforceJoinOrder, final int timeout, final GridQueryCancel cancel) throws IgniteCheckedException {
    final Connection conn = connectionForSchema(schemaName);
    H2Utils.setupConnection(conn, false, enforceJoinOrder);
    final PreparedStatement stmt = preparedStatementWithParams(conn, qry, params, true);
    if (GridSqlQueryParser.checkMultipleStatements(stmt))
        throw new IgniteSQLException("Multiple statements queries are not supported for local queries");
    Prepared p = GridSqlQueryParser.prepared(stmt);
    if (DmlStatementsProcessor.isDmlStatement(p)) {
        SqlFieldsQuery fldsQry = new SqlFieldsQuery(qry);
        if (params != null)
            fldsQry.setArgs(params.toArray());
        fldsQry.setEnforceJoinOrder(enforceJoinOrder);
        fldsQry.setTimeout(timeout, TimeUnit.MILLISECONDS);
        return dmlProc.updateSqlFieldsLocal(schemaName, conn, p, fldsQry, filter, cancel);
    } else if (DdlStatementsProcessor.isDdlStatement(p))
        throw new IgniteSQLException("DDL statements are supported for the whole cluster only", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    List<GridQueryFieldMetadata> meta;
    try {
        meta = H2Utils.meta(stmt.getMetaData());
    } catch (SQLException e) {
        throw new IgniteCheckedException("Cannot prepare query metadata", e);
    }
    final GridH2QueryContext ctx = new GridH2QueryContext(nodeId, nodeId, 0, LOCAL).filter(filter).distributedJoinMode(OFF);
    return new GridQueryFieldsResultAdapter(meta, null) {

        @Override
        public GridCloseableIterator<List<?>> iterator() throws IgniteCheckedException {
            assert GridH2QueryContext.get() == null;
            GridH2QueryContext.set(ctx);
            GridRunningQueryInfo run = new GridRunningQueryInfo(qryIdGen.incrementAndGet(), qry, SQL_FIELDS, schemaName, U.currentTimeMillis(), cancel, true);
            runs.putIfAbsent(run.id(), run);
            try {
                ResultSet rs = executeSqlQueryWithTimer(stmt, conn, qry, params, timeout, cancel);
                return new H2FieldsIterator(rs);
            } finally {
                GridH2QueryContext.clearThreadLocal();
                runs.remove(run.id());
            }
        }
    };
}
Also used : GridQueryFieldsResultAdapter(org.apache.ignite.internal.processors.query.GridQueryFieldsResultAdapter) SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) Connection(java.sql.Connection) Prepared(org.h2.command.Prepared) GridRunningQueryInfo(org.apache.ignite.internal.processors.query.GridRunningQueryInfo) GridQueryFieldMetadata(org.apache.ignite.internal.processors.query.GridQueryFieldMetadata) PreparedStatement(java.sql.PreparedStatement) SqlFieldsQuery(org.apache.ignite.cache.query.SqlFieldsQuery) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) GridH2QueryContext(org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext)

Example 25 with Schema

use of org.h2.schema.Schema in project ignite by apache.

the class IgniteH2Indexing method unregisterCache.

/**
 * {@inheritDoc}
 */
@Override
public void unregisterCache(GridCacheContext cctx, boolean rmvIdx) {
    rowCache.onCacheUnregistered(cctx);
    String cacheName = cctx.name();
    String schemaName = schema(cacheName);
    H2Schema schema = schemas.get(schemaName);
    if (schema != null) {
        mapQryExec.onCacheStop(cacheName);
        dmlProc.onCacheStop(cacheName);
        // Remove this mapping only after callback to DML proc - it needs that mapping internally
        cacheName2schema.remove(cacheName);
        // Drop tables.
        Collection<H2TableDescriptor> rmvTbls = new HashSet<>();
        for (H2TableDescriptor tbl : schema.tables()) {
            if (F.eq(tbl.cache().name(), cacheName)) {
                try {
                    tbl.table().setRemoveIndexOnDestroy(rmvIdx);
                    dropTable(tbl);
                } catch (IgniteCheckedException e) {
                    U.error(log, "Failed to drop table on cache stop (will ignore): " + tbl.fullTableName(), e);
                }
                schema.drop(tbl);
                rmvTbls.add(tbl);
            }
        }
        if (!isDefaultSchema(schemaName)) {
            synchronized (schemaMux) {
                if (schema.decrementUsageCount() == 0) {
                    schemas.remove(schemaName);
                    try {
                        dropSchema(schemaName);
                    } catch (IgniteCheckedException e) {
                        U.error(log, "Failed to drop schema on cache stop (will ignore): " + cacheName, e);
                    }
                }
            }
        }
        stmtCache.clear();
        for (H2TableDescriptor tbl : rmvTbls) {
            for (Index idx : tbl.table().getIndexes()) idx.close(null);
        }
        int cacheId = CU.cacheId(cacheName);
        for (Iterator<Map.Entry<H2TwoStepCachedQueryKey, H2TwoStepCachedQuery>> it = twoStepCache.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<H2TwoStepCachedQueryKey, H2TwoStepCachedQuery> e = it.next();
            GridCacheTwoStepQuery qry = e.getValue().query();
            if (!F.isEmpty(qry.cacheIds()) && qry.cacheIds().contains(cacheId))
                it.remove();
        }
    }
}
Also used : GridCacheTwoStepQuery(org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery) Index(org.h2.index.Index) H2TreeIndex(org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex) IgniteSystemProperties.getString(org.apache.ignite.IgniteSystemProperties.getString) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) GridBoundedConcurrentLinkedHashMap(org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Aggregations

ResultSet (java.sql.ResultSet)12 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)10 PreparedStatement (java.sql.PreparedStatement)9 Statement (java.sql.Statement)9 ArrayList (java.util.ArrayList)9 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)9 SimpleResultSet (org.h2.tools.SimpleResultSet)9 List (java.util.List)8 Schema (io.s4.schema.Schema)7 Connection (java.sql.Connection)7 SQLException (java.sql.SQLException)7 Property (io.s4.schema.Schema.Property)6 LinkedHashMap (java.util.LinkedHashMap)4 Map (java.util.Map)4 IgniteException (org.apache.ignite.IgniteException)4 IgniteSystemProperties.getString (org.apache.ignite.IgniteSystemProperties.getString)4 GridH2QueryContext (org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext)4 GridSqlStatement (org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement)4 Schema (org.h2.schema.Schema)4 TypeLiteral (com.google.inject.TypeLiteral)3