Search in sources :

Example 11 with IgniteSQLException

use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.

the class GridSqlQueryParser method parseCreateTable.

/**
 * Parse {@code CREATE TABLE} statement.
 *
 * @param createTbl {@code CREATE TABLE} statement.
 * @see <a href="http://h2database.com/html/grammar.html#create_table">H2 {@code CREATE TABLE} spec.</a>
 */
private GridSqlCreateTable parseCreateTable(CreateTable createTbl) {
    GridSqlCreateTable res = new GridSqlCreateTable();
    res.templateName(QueryUtils.TEMPLATE_PARTITIONED);
    Query qry = CREATE_TABLE_QUERY.get(createTbl);
    if (qry != null)
        throw new IgniteSQLException("CREATE TABLE ... AS ... syntax is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    List<DefineCommand> constraints = CREATE_TABLE_CONSTRAINTS.get(createTbl);
    if (constraints.size() == 0)
        throw new IgniteSQLException("No PRIMARY KEY defined for CREATE TABLE", IgniteQueryErrorCode.PARSING);
    if (constraints.size() > 1)
        throw new IgniteSQLException("Too many constraints - only PRIMARY KEY is supported for CREATE TABLE", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    DefineCommand constraint = constraints.get(0);
    if (!(constraint instanceof AlterTableAddConstraint))
        throw new IgniteSQLException("Unsupported type of constraint for CREATE TABLE - only PRIMARY KEY " + "is supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    AlterTableAddConstraint alterTbl = (AlterTableAddConstraint) constraint;
    if (alterTbl.getType() != Command.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY)
        throw new IgniteSQLException("Unsupported type of constraint for CREATE TABLE - only PRIMARY KEY " + "is supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    Schema schema = SCHEMA_COMMAND_SCHEMA.get(createTbl);
    res.schemaName(schema.getName());
    CreateTableData data = CREATE_TABLE_DATA.get(createTbl);
    LinkedHashMap<String, GridSqlColumn> cols = new LinkedHashMap<>(data.columns.size());
    for (Column col : data.columns) cols.put(col.getName(), parseColumn(col));
    if (cols.containsKey(QueryUtils.KEY_FIELD_NAME.toUpperCase()) || cols.containsKey(QueryUtils.VAL_FIELD_NAME.toUpperCase()))
        throw new IgniteSQLException("Direct specification of _KEY and _VAL columns is forbidden", IgniteQueryErrorCode.PARSING);
    IndexColumn[] pkIdxCols = CREATE_TABLE_PK.get(createTbl);
    if (F.isEmpty(pkIdxCols))
        throw new AssertionError("No PRIMARY KEY columns specified");
    LinkedHashSet<String> pkCols = new LinkedHashSet<>();
    for (IndexColumn pkIdxCol : pkIdxCols) {
        GridSqlColumn gridCol = cols.get(pkIdxCol.columnName);
        assert gridCol != null;
        pkCols.add(gridCol.columnName());
    }
    int keyColsNum = pkCols.size();
    int valColsNum = cols.size() - keyColsNum;
    if (valColsNum == 0)
        throw new IgniteSQLException("Table must have at least one non PRIMARY KEY column.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    res.columns(cols);
    res.primaryKeyColumns(pkCols);
    res.tableName(data.tableName);
    res.ifNotExists(CREATE_TABLE_IF_NOT_EXISTS.get(createTbl));
    List<String> extraParams = data.tableEngineParams != null ? new ArrayList<String>() : null;
    if (data.tableEngineParams != null)
        for (String s : data.tableEngineParams) extraParams.addAll(F.asList(s.split(",")));
    res.params(extraParams);
    if (!F.isEmpty(extraParams)) {
        Map<String, String> params = new HashMap<>();
        for (String p : extraParams) {
            String[] parts = p.split(PARAM_NAME_VALUE_SEPARATOR);
            if (parts.length > 2)
                throw new IgniteSQLException("Invalid parameter (key[=value] expected): " + p, IgniteQueryErrorCode.PARSING);
            String name = parts[0].trim().toUpperCase();
            String val = parts.length > 1 ? parts[1].trim() : null;
            if (F.isEmpty(name))
                throw new IgniteSQLException("Invalid parameter (key[=value] expected): " + p, IgniteQueryErrorCode.PARSING);
            if (params.put(name, val) != null)
                throw new IgniteSQLException("Duplicate parameter: " + p, IgniteQueryErrorCode.PARSING);
        }
        for (Map.Entry<String, String> e : params.entrySet()) processExtraParam(e.getKey(), e.getValue(), res);
    }
    // Process key wrapping.
    Boolean wrapKey = res.wrapKey();
    if (wrapKey != null && !wrapKey) {
        if (keyColsNum > 1) {
            throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when composite primary key exists.", IgniteQueryErrorCode.PARSING);
        }
        if (!F.isEmpty(res.keyTypeName())) {
            throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when " + PARAM_KEY_TYPE + " is set.", IgniteQueryErrorCode.PARSING);
        }
    }
    boolean wrapKey0 = (res.wrapKey() != null && res.wrapKey()) || !F.isEmpty(res.keyTypeName()) || keyColsNum > 1;
    res.wrapKey(wrapKey0);
    // Process value wrapping.
    Boolean wrapVal = res.wrapValue();
    if (wrapVal != null && !wrapVal) {
        if (valColsNum > 1) {
            throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when multiple non-primary key " + "columns exist.", IgniteQueryErrorCode.PARSING);
        }
        if (!F.isEmpty(res.valueTypeName())) {
            throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when " + PARAM_VAL_TYPE + " is set.", IgniteQueryErrorCode.PARSING);
        }
        res.wrapValue(false);
    } else
        // By default value is always wrapped to allow for ALTER TABLE ADD COLUMN commands.
        res.wrapValue(true);
    if (!F.isEmpty(res.valueTypeName()) && F.eq(res.keyTypeName(), res.valueTypeName()))
        throw new IgniteSQLException("Key and value type names " + "should be different for CREATE TABLE: " + res.valueTypeName(), IgniteQueryErrorCode.PARSING);
    if (res.affinityKey() == null) {
        LinkedHashSet<String> pkCols0 = res.primaryKeyColumns();
        if (!F.isEmpty(pkCols0) && pkCols0.size() == 1 && wrapKey0)
            res.affinityKey(pkCols0.iterator().next());
    }
    return res;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SqlFieldsQuery(org.apache.ignite.cache.query.SqlFieldsQuery) Query(org.h2.command.dml.Query) LinkedHashMap(java.util.LinkedHashMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Schema(org.h2.schema.Schema) DefineCommand(org.h2.command.ddl.DefineCommand) LinkedHashMap(java.util.LinkedHashMap) IndexColumn(org.h2.table.IndexColumn) GridSqlType.fromColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) CreateTableData(org.h2.command.ddl.CreateTableData) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap)

Example 12 with IgniteSQLException

use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.

the class DmlStatementsProcessor method doDelete.

/**
 * Perform DELETE operation on top of results of SELECT.
 * @param cctx Cache context.
 * @param cursor SELECT results.
 * @param pageSize Batch size for streaming, anything <= 0 for single page operations.
 * @return Results of DELETE (number of items affected AND keys that failed to be updated).
 */
@SuppressWarnings({ "unchecked", "ConstantConditions", "ThrowableResultOfMethodCallIgnored" })
private UpdateResult doDelete(GridCacheContext cctx, Iterable<List<?>> cursor, int pageSize) throws IgniteCheckedException {
    DmlBatchSender sender = new DmlBatchSender(cctx, pageSize, 1);
    for (List<?> row : cursor) {
        if (row.size() != 2) {
            U.warn(log, "Invalid row size on DELETE - expected 2, got " + row.size());
            continue;
        }
        sender.add(row.get(0), new ModifyingEntryProcessor(row.get(1), RMV), 0);
    }
    sender.flush();
    SQLException resEx = sender.error();
    if (resEx != null) {
        if (!F.isEmpty(sender.failedKeys())) {
            // Don't go for a re-run if processing of some keys yielded exceptions and report keys that
            // had been modified concurrently right away.
            String msg = "Failed to DELETE some keys because they had been modified concurrently " + "[keys=" + sender.failedKeys() + ']';
            SQLException conEx = createJdbcSqlException(msg, IgniteQueryErrorCode.CONCURRENT_UPDATE);
            conEx.setNextException(resEx);
            resEx = conEx;
        }
        throw new IgniteSQLException(resEx);
    }
    return new UpdateResult(sender.updateCount(), sender.failedKeys().toArray());
}
Also used : SQLException(java.sql.SQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) DmlBatchSender(org.apache.ignite.internal.processors.query.h2.dml.DmlBatchSender)

Example 13 with IgniteSQLException

use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.

the class IgniteH2Indexing method doRunPrepared.

/**
 * Execute an all-ready {@link SqlFieldsQuery}.
 * @param schemaName Schema name.
 * @param prepared H2 command.
 * @param qry Fields query with flags.
 * @param twoStepQry Two-step query if this query must be executed in a distributed way.
 * @param meta Metadata for {@code twoStepQry}.
 * @param keepBinary Whether binary objects must not be deserialized automatically.
 * @param cancel Query cancel state holder.    @return Query result.
 */
private List<? extends FieldsQueryCursor<List<?>>> doRunPrepared(String schemaName, Prepared prepared, SqlFieldsQuery qry, GridCacheTwoStepQuery twoStepQry, List<GridQueryFieldMetadata> meta, boolean keepBinary, GridQueryCancel cancel) {
    String sqlQry = qry.getSql();
    boolean loc = qry.isLocal();
    IndexingQueryFilter filter = (loc ? backupFilter(null, qry.getPartitions()) : null);
    if (!prepared.isQuery()) {
        if (DmlStatementsProcessor.isDmlStatement(prepared)) {
            try {
                Connection conn = connectionForSchema(schemaName);
                if (!loc)
                    return dmlProc.updateSqlFieldsDistributed(schemaName, conn, prepared, qry, cancel);
                else {
                    final GridQueryFieldsResult updRes = dmlProc.updateSqlFieldsLocal(schemaName, conn, prepared, qry, filter, cancel);
                    return Collections.singletonList(new QueryCursorImpl<>(new Iterable<List<?>>() {

                        @Override
                        public Iterator<List<?>> iterator() {
                            try {
                                return new GridQueryCacheObjectsIterator(updRes.iterator(), objectContext(), true);
                            } catch (IgniteCheckedException e) {
                                throw new IgniteException(e);
                            }
                        }
                    }, cancel));
                }
            } catch (IgniteCheckedException e) {
                throw new IgniteSQLException("Failed to execute DML statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
            }
        }
        if (DdlStatementsProcessor.isDdlStatement(prepared)) {
            if (loc)
                throw new IgniteSQLException("DDL statements are not supported for LOCAL caches", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
            try {
                return Collections.singletonList(ddlProc.runDdlStatement(sqlQry, prepared));
            } catch (IgniteCheckedException e) {
                throw new IgniteSQLException("Failed to execute DDL statement [stmt=" + sqlQry + ']', e);
            }
        }
        if (prepared instanceof NoOperation) {
            QueryCursorImpl<List<?>> resCur = (QueryCursorImpl<List<?>>) new QueryCursorImpl(Collections.singletonList(Collections.singletonList(0L)), null, false);
            resCur.fieldsMeta(UPDATE_RESULT_META);
            return Collections.singletonList(resCur);
        }
        throw new IgniteSQLException("Unsupported DDL/DML operation: " + prepared.getClass().getName());
    }
    if (twoStepQry != null) {
        if (log.isDebugEnabled())
            log.debug("Parsed query: `" + sqlQry + "` into two step query: " + twoStepQry);
        checkQueryType(qry, true);
        return Collections.singletonList(doRunDistributedQuery(schemaName, qry, twoStepQry, meta, keepBinary, cancel));
    }
    // We've encountered a local query, let's just run it.
    try {
        return Collections.singletonList(queryLocalSqlFields(schemaName, qry, keepBinary, filter, cancel));
    } catch (IgniteCheckedException e) {
        throw new IgniteSQLException("Failed to execute local statement [stmt=" + sqlQry + ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
    }
}
Also used : IndexingQueryFilter(org.apache.ignite.spi.indexing.IndexingQueryFilter) Connection(java.sql.Connection) QueryCursorImpl(org.apache.ignite.internal.processors.cache.QueryCursorImpl) IgniteSystemProperties.getString(org.apache.ignite.IgniteSystemProperties.getString) GridQueryCacheObjectsIterator(org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator) GridQueryFieldsResult(org.apache.ignite.internal.processors.query.GridQueryFieldsResult) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) NoOperation(org.h2.command.dml.NoOperation) IgniteException(org.apache.ignite.IgniteException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) ArrayList(java.util.ArrayList) List(java.util.List)

Example 14 with IgniteSQLException

use of org.apache.ignite.internal.processors.query.IgniteSQLException 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 15 with IgniteSQLException

use of org.apache.ignite.internal.processors.query.IgniteSQLException 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)

Aggregations

IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)57 SQLException (java.sql.SQLException)20 ArrayList (java.util.ArrayList)19 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)17 List (java.util.List)16 Column (org.h2.table.Column)13 IgniteException (org.apache.ignite.IgniteException)11 PreparedStatement (java.sql.PreparedStatement)9 GridQueryProperty (org.apache.ignite.internal.processors.query.GridQueryProperty)9 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)9 Connection (java.sql.Connection)8 IgniteSystemProperties.getString (org.apache.ignite.IgniteSystemProperties.getString)8 LinkedHashMap (java.util.LinkedHashMap)7 SqlFieldsQuery (org.apache.ignite.cache.query.SqlFieldsQuery)7 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)7 QueryCursorImpl (org.apache.ignite.internal.processors.cache.QueryCursorImpl)7 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)7 UUID (java.util.UUID)6 GridQueryTypeDescriptor (org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor)6 GridSqlColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn)6