You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2019/02/15 05:26:31 UTC
[ignite] branch master updated: IGNITE-11279: SQL: Removed
"prepared" from parser's cache.
This is an automated email from the ASF dual-hosted git repository.
vozerov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 9860670 IGNITE-11279: SQL: Removed "prepared" from parser's cache.
9860670 is described below
commit 98606705ef26b30bd006c31c74989a9ede74054b
Author: devozerov <pp...@gmail.com>
AuthorDate: Fri Feb 15 08:25:49 2019 +0300
IGNITE-11279: SQL: Removed "prepared" from parser's cache.
---
.../internal/processors/cache/mvcc/MvccUtils.java | 13 +--
.../internal/processors/query/h2/H2Utils.java | 6 +-
.../processors/query/h2/IgniteH2Indexing.java | 106 +++++++++++----------
.../internal/processors/query/h2/QueryParser.java | 62 +++++++++++-
.../processors/query/h2/QueryParserResultDml.java | 24 +++--
.../processors/query/h2/dml/UpdatePlanBuilder.java | 94 ++----------------
.../query/h2/sql/GridSqlQueryParser.java | 40 ++++++++
7 files changed, 191 insertions(+), 154 deletions(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
index f904966..225af81 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/MvccUtils.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.mvcc;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.TransactionConfiguration;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
@@ -845,14 +846,14 @@ public class MvccUtils {
/**
* Throws atomicity modes compatibility validation exception.
*
- * @param ctx1 Cache context.
- * @param ctx2 Another cache context.
+ * @param ccfg1 Config 1.
+ * @param ccfg2 Config 2.
*/
- public static void throwAtomicityModesMismatchException(GridCacheContext ctx1, GridCacheContext ctx2) {
+ public static void throwAtomicityModesMismatchException(CacheConfiguration ccfg1, CacheConfiguration ccfg2) {
throw new IgniteException("Caches with transactional_snapshot atomicity mode cannot participate in the same" +
- " transaction with caches having another atomicity mode. [cacheName=" + ctx1.name() +
- ", cacheMode=" + ctx1.config().getAtomicityMode() +
- ", anotherCacheName=" + ctx2.name() + " anotherCacheMode=" + ctx2.config().getAtomicityMode() + ']');
+ " transaction with caches having another atomicity mode. [cacheName=" + ccfg1.getName() +
+ ", cacheMode=" + ccfg1.getAtomicityMode() + ", anotherCacheName=" + ccfg2.getName() +
+ " anotherCacheMode=" + ccfg2.getAtomicityMode() + ']');
}
/** */
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
index 50b8def..b86a481 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Utils.java
@@ -775,9 +775,7 @@ public class H2Utils {
if (tbl != null) {
checkAndStartNotStartedCache(idx.kernalContext(), tbl);
- int cacheId = tbl.cacheId();
-
- caches0.add(cacheId);
+ caches0.add(tbl.cacheId());
}
}
}
@@ -814,7 +812,7 @@ public class H2Utils {
cctx0 = cctx;
}
else if (cctx.mvccEnabled() != mvccEnabled)
- MvccUtils.throwAtomicityModesMismatchException(cctx0, cctx);
+ MvccUtils.throwAtomicityModesMismatchException(cctx0.config(), cctx.config());
}
return mvccEnabled;
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 0b44cfc..7f24399 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -502,6 +502,8 @@ public class IgniteH2Indexing implements GridQueryIndexing {
Prepared p = GridSqlQueryParser.prepared(stmt);
if (GridSqlQueryParser.isDml(p)) {
+ QueryParserResultDml dml = parser.prepareDmlStatement(p);
+
SqlFieldsQuery fldsQry = new SqlFieldsQuery(qry);
if (params != null)
@@ -511,7 +513,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
fldsQry.setTimeout(qryTimeout, TimeUnit.MILLISECONDS);
fldsQry.setDataPageScanEnabled(dataPageScanEnabled);
- UpdateResult updRes = executeUpdate(schemaName, conn, p, fldsQry, true, filter, cancel);
+ UpdateResult updRes = executeUpdate(schemaName, conn, dml, fldsQry, true, filter, cancel);
List<?> updResRow = Collections.singletonList(updRes.counter());
@@ -741,9 +743,9 @@ public class IgniteH2Indexing implements GridQueryIndexing {
checkStatementStreamable(stmt);
- Prepared p = GridSqlQueryParser.prepared(stmt);
+ QueryParserResultDml dml = parser.prepareDmlStatement(stmt);
- UpdatePlan plan = updatePlan(schemaName, conn, p, null, true);
+ UpdatePlan plan = updatePlan(schemaName, conn, dml, null, true);
IgniteDataStreamer<?, ?> streamer = cliCtx.streamerForCache(plan.cacheContext().name());
@@ -778,11 +780,9 @@ public class IgniteH2Indexing implements GridQueryIndexing {
try {
checkStatementStreamable(stmt);
- Prepared p = GridSqlQueryParser.prepared(stmt);
-
- assert p != null;
+ QueryParserResultDml dml = parser.prepareDmlStatement(stmt);
- final UpdatePlan plan = updatePlan(schemaName, null, p, null, true);
+ final UpdatePlan plan = updatePlan(schemaName, null, dml, null, true);
assert plan.isLocalSubquery();
@@ -1172,7 +1172,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
ctx0 = cctx;
}
else if (mvccEnabled != cctx.mvccEnabled())
- MvccUtils.throwAtomicityModesMismatchException(ctx0, cctx);
+ MvccUtils.throwAtomicityModesMismatchException(ctx0.config(), cctx.config());
}
}
@@ -1505,42 +1505,31 @@ public class IgniteH2Indexing implements GridQueryIndexing {
IndexingQueryFilter filter = (loc ? backupFilter(null, qry.getPartitions()) : null);
if (dml != null) {
- Prepared prepared = dml.prepared();
-
Long qryId = registerRunningQuery(schemaName, cancel, sqlQry, loc, registerAsNewQry);
boolean fail = false;
try {
- if (GridSqlQueryParser.isDml(prepared)) {
- try {
- Connection conn = connMgr.connectionForThread().connection(schemaName);
+ Connection conn = connMgr.connectionForThread().connection(schemaName);
- if (!loc)
- return executeUpdateDistributed(schemaName, conn, prepared, qry, cancel);
- else {
- UpdateResult updRes = executeUpdate(schemaName, conn, prepared, qry, true, filter, cancel);
+ if (!loc)
+ return executeUpdateDistributed(schemaName, conn, dml , qry, cancel);
+ else {
+ UpdateResult updRes = executeUpdate(schemaName, conn, dml , qry, true, filter, cancel);
- return Collections.singletonList(new QueryCursorImpl<>(new Iterable<List<?>>() {
- @SuppressWarnings("NullableProblems")
- @Override public Iterator<List<?>> iterator() {
- return new IgniteSingletonIterator<>(Collections.singletonList(updRes.counter()));
- }
- }, cancel));
+ return Collections.singletonList(new QueryCursorImpl<>(new Iterable<List<?>>() {
+ @SuppressWarnings("NullableProblems")
+ @Override public Iterator<List<?>> iterator() {
+ return new IgniteSingletonIterator<>(Collections.singletonList(updRes.counter()));
}
- }
- catch (IgniteCheckedException e) {
- fail = true;
-
- throw new IgniteSQLException("Failed to execute DML statement [stmt=" + sqlQry +
- ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
- }
+ }, cancel));
}
-
+ }
+ catch (IgniteCheckedException e) {
fail = true;
- throw new IgniteSQLException("Unsupported DDL/DML operation: " + prepared.getClass().getName(),
- IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+ throw new IgniteSQLException("Failed to execute DML statement [stmt=" + sqlQry +
+ ", params=" + Arrays.deepToString(qry.getArgs()) + "]", e);
}
finally {
runningQryMgr.unregister(qryId, fail);
@@ -1692,9 +1681,9 @@ public class IgniteH2Indexing implements GridQueryIndexing {
IndexingQueryFilter filter = backupFilter(topVer, parts);
- Prepared prepared = GridSqlQueryParser.prepared(stmt);
+ QueryParserResultDml dml = parser.prepareDmlStatement(stmt);
- UpdatePlan plan = updatePlan(schema, conn, prepared, fldsQry, loc);
+ UpdatePlan plan = updatePlan(schema, conn, dml, fldsQry, loc);
GridCacheContext planCctx = plan.cacheContext();
@@ -1919,8 +1908,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
H2Utils.setupConnection(conn, false, qry.isEnforceJoinOrder());
- PreparedStatement stmt = preparedStatementWithParams(conn, qry.getSql(),
- Arrays.asList(qry.getArgs()), true);
+ PreparedStatement stmt = preparedStatementWithParams(conn, qry.getSql(), Arrays.asList(qry.getArgs()), true);
Connection c;
@@ -1931,7 +1919,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
throw new IgniteCheckedException(e);
}
- return executeUpdate(schemaName, c, GridSqlQueryParser.prepared(stmt), qry, loc, filter, cancel);
+ return executeUpdate(schemaName, c, parser.prepareDmlStatement(stmt), qry, loc, filter, cancel);
}
/**
@@ -2472,7 +2460,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
/**
* @param schemaName Schema.
* @param conn Connection.
- * @param prepared Prepared statement.
+ * @param dml DML statement.
* @param fieldsQry Initial query
* @param cancel Query cancel.
* @return Update result wrapped into {@link GridQueryFieldsResult}
@@ -2482,7 +2470,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
private List<QueryCursorImpl<List<?>>> executeUpdateDistributed(
String schemaName,
Connection conn,
- Prepared prepared,
+ QueryParserResultDml dml,
SqlFieldsQuery fieldsQry,
GridQueryCancel cancel
) throws IgniteCheckedException {
@@ -2493,7 +2481,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
List<Object[]> argss = fieldsQry0.batchedArguments();
- UpdatePlan plan = updatePlan(schemaName, conn, prepared, fieldsQry0, false);
+ UpdatePlan plan = updatePlan(schemaName, conn, dml, fieldsQry0, false);
GridCacheContext<?, ?> cctx = plan.cacheContext();
@@ -2529,7 +2517,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
UpdateResult res;
try {
- res = executeUpdate(schemaName, conn, prepared, qry0, false, null, cancel);
+ res = executeUpdate(schemaName, conn, dml, qry0, false, null, cancel);
cntPerRow[cntr++] = (int)res.counter();
@@ -2568,7 +2556,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
return resCurs;
}
else {
- UpdateResult res = executeUpdate(schemaName, conn, prepared, fieldsQry, false, null, cancel);
+ UpdateResult res = executeUpdate(schemaName, conn, dml, fieldsQry, false, null, cancel);
res.throwIfError();
@@ -2586,7 +2574,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
*
* @param schemaName Schema.
* @param conn Connection.
- * @param prepared Prepared statement.
+ * @param dml DML command.
* @param fieldsQry Original query.
* @param loc Query locality flag.
* @param filters Cache name and key filter.
@@ -2594,14 +2582,14 @@ public class IgniteH2Indexing implements GridQueryIndexing {
* @return Update result (modified items count and failed keys).
* @throws IgniteCheckedException if failed.
*/
- private UpdateResult executeUpdate(String schemaName, Connection conn, Prepared prepared,
+ private UpdateResult executeUpdate(String schemaName, Connection conn, QueryParserResultDml dml,
SqlFieldsQuery fieldsQry, boolean loc, IndexingQueryFilter filters, GridQueryCancel cancel)
throws IgniteCheckedException {
Object[] errKeys = null;
long items = 0;
- UpdatePlan plan = updatePlan(schemaName, conn, prepared, fieldsQry, loc);
+ UpdatePlan plan = updatePlan(schemaName, conn, dml, fieldsQry, loc);
GridCacheContext<?, ?> cctx = plan.cacheContext();
@@ -2859,7 +2847,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
*
* @param schema Schema.
* @param conn Connection.
- * @param p Prepared statement.
+ * @param dml Command.
* @param fieldsQry Original fields query.
* @param loc Local query flag.
* @return Update plan.
@@ -2868,22 +2856,40 @@ public class IgniteH2Indexing implements GridQueryIndexing {
private UpdatePlan updatePlan(
String schema,
Connection conn,
- Prepared p,
+ QueryParserResultDml dml,
SqlFieldsQuery fieldsQry,
boolean loc
) throws IgniteCheckedException {
+ // Disallow updates on SYSTEM schema.
if (F.eq(QueryUtils.SCHEMA_SYS, schema))
throw new IgniteSQLException("DML statements are not supported on " + schema + " schema",
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
- H2CachedStatementKey planKey = new H2CachedStatementKey(schema, p.getSQL(), fieldsQry, loc);
+ // Disallow updates inside transaction if this is not MVCC mode.
+ boolean inTx = ctx.cache().context().tm().inUserTx();
+
+ if (!dml.mvccEnabled() && !updateInTxAllowed && inTx) {
+ throw new IgniteSQLException("DML statements are not allowed inside a transaction over " +
+ "cache(s) with TRANSACTIONAL atomicity mode (change atomicity mode to " +
+ "TRANSACTIONAL_SNAPSHOT or disable this error message with system property " +
+ "\"IGNITE_ALLOW_DML_INSIDE_TRANSACTION\"");
+ }
+
+ H2CachedStatementKey planKey = new H2CachedStatementKey(schema, dml.statement().getSQL(), fieldsQry, loc);
UpdatePlan res = updatePlanCache.get(planKey);
if (res != null)
return res;
- res = UpdatePlanBuilder.planForStatement(p, loc, this, conn, fieldsQry, updateInTxAllowed);
+ res = UpdatePlanBuilder.planForStatement(
+ dml.statement(),
+ dml.mvccEnabled(),
+ loc,
+ this,
+ conn,
+ fieldsQry
+ );
// Don't cache re-runs
UpdatePlan oldRes = updatePlanCache.putIfAbsent(planKey, res);
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
index 54a3bbd..13810cb 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
@@ -21,14 +21,18 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContextInfo;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils;
import org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
import org.apache.ignite.internal.processors.query.IgniteSQLException;
import org.apache.ignite.internal.processors.query.h2.dml.DmlUtils;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
import org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser;
import org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuerySplitter;
import org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement;
@@ -308,8 +312,11 @@ public class QueryParser {
return new QueryParserResult(newQry, remainingQry, null, null, cmd);
}
- else if (GridSqlQueryParser.isDml(prepared))
- return new QueryParserResult(newQry, remainingQry, null ,new QueryParserResultDml(prepared), null);
+ else if (GridSqlQueryParser.isDml(prepared)) {
+ QueryParserResultDml dml = prepareDmlStatement(prepared);
+
+ return new QueryParserResult(newQry, remainingQry, null, dml, null);
+ }
else if (!prepared.isQuery()) {
throw new IgniteSQLException("Unsupported statement: " + newQry.getSql(),
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
@@ -387,6 +394,57 @@ public class QueryParser {
}
/**
+ * Prepare DML statement.
+ *
+ * @param preparedStmt Prepared statement.
+ * @return Statement.
+ */
+ public QueryParserResultDml prepareDmlStatement(PreparedStatement preparedStmt) {
+ Prepared prep = GridSqlQueryParser.prepared(preparedStmt);
+
+ return prepareDmlStatement(prep);
+ }
+
+ /**
+ * Prepare DML statement.
+ *
+ * @param prepared Prepared.
+ * @return Statement.
+ */
+ public QueryParserResultDml prepareDmlStatement(Prepared prepared) {
+ // Prepare AST.
+ GridSqlQueryParser parser = new GridSqlQueryParser(false);
+
+ GridSqlStatement stmt = parser.parse(prepared);
+
+ List<GridH2Table> tbls = parser.tablesForDml();
+
+ // Check if caches are started because we may need to collect affinity info later on, so they needs to be
+ // available on local node.
+ for (GridH2Table h2tbl : tbls)
+ H2Utils.checkAndStartNotStartedCache(idx.kernalContext(), h2tbl);
+
+ // Check MVCC mode.
+ GridCacheContextInfo ctx = null;
+ boolean mvccEnabled = false;
+
+ for (GridH2Table h2tbl : tbls) {
+ GridCacheContextInfo curCtx = h2tbl.cacheInfo();
+ boolean curMvccEnabled = curCtx.config().getAtomicityMode() == CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT;
+
+ if (ctx == null) {
+ ctx = curCtx;
+
+ mvccEnabled = curMvccEnabled;
+ }
+ else if (curMvccEnabled != mvccEnabled)
+ MvccUtils.throwAtomicityModesMismatchException(ctx.config(), curCtx.config());
+ }
+
+ return new QueryParserResultDml(stmt, mvccEnabled);
+ }
+
+ /**
* Clear cached plans.
*/
public void clearCache() {
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParserResultDml.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParserResultDml.java
index 5e91288..03067e0 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParserResultDml.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParserResultDml.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.query.h2;
+import org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement;
import org.h2.command.Prepared;
/**
@@ -24,21 +25,32 @@ import org.h2.command.Prepared;
*/
public class QueryParserResultDml {
/** Command. */
- private final Prepared prepared;
+ private final GridSqlStatement stmt;
+
+ /** MVCC enabled flag. */
+ private final boolean mvccEnabled;
/**
* Constructor.
*
- * @param prepared Command.
+ * @param stmt Command.
*/
- public QueryParserResultDml(Prepared prepared) {
- this.prepared = prepared;
+ public QueryParserResultDml(GridSqlStatement stmt, boolean mvccEnabled) {
+ this.stmt = stmt;
+ this.mvccEnabled = mvccEnabled;
}
/**
* @return Command.
*/
- public Prepared prepared() {
- return prepared;
+ public GridSqlStatement statement() {
+ return stmt;
+ }
+
+ /**
+ * @return MVCC enabled.
+ */
+ public boolean mvccEnabled() {
+ return mvccEnabled;
}
}
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
index c3f55d5..709ce17 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
@@ -32,7 +32,6 @@ import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryObjectBuilder;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils;
import org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery;
import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
@@ -45,8 +44,6 @@ import org.apache.ignite.internal.processors.query.h2.H2Utils;
import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
-import org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias;
-import org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst;
import org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn;
import org.apache.ignite.internal.processors.query.h2.sql.GridSqlConst;
import org.apache.ignite.internal.processors.query.h2.sql.GridSqlDelete;
@@ -69,7 +66,6 @@ import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteClosure;
-import org.h2.command.Prepared;
import org.h2.table.Column;
import org.jetbrains.annotations.Nullable;
@@ -92,7 +88,8 @@ public final class UpdatePlanBuilder {
* Generate SELECT statements to retrieve data for modifications from and find fast UPDATE or DELETE args,
* if available.
*
- * @param prepared H2's {@link Prepared}.
+ * @param stmt Statement.
+ * @param mvccEnabled MVCC enabled flag.
* @param loc Local query flag.
* @param idx Indexing.
* @param conn Connection.
@@ -101,98 +98,23 @@ public final class UpdatePlanBuilder {
*/
@SuppressWarnings("ConstantConditions")
public static UpdatePlan planForStatement(
- Prepared prepared,
+ GridSqlStatement stmt,
+ boolean mvccEnabled,
boolean loc,
IgniteH2Indexing idx,
@Nullable Connection conn,
- @Nullable SqlFieldsQuery fieldsQry,
- boolean dmlInsideTxAllowed
- )
- throws IgniteCheckedException {
- assert !prepared.isQuery();
-
- GridSqlQueryParser parser = new GridSqlQueryParser(false);
-
- GridSqlStatement stmt = parser.parse(prepared);
-
-
- List<GridH2Table> tbls = extractTablesParticipateAtQuery(parser);
-
- GridCacheContext prevCctx = null;
- boolean mvccEnabled = false;
-
- for (GridH2Table h2tbl : tbls) {
- H2Utils.checkAndStartNotStartedCache(idx.kernalContext(), h2tbl);
-
- if (prevCctx == null) {
- prevCctx = h2tbl.cacheContext();
-
- assert prevCctx != null : h2tbl.cacheName() + " is not initted";
-
- mvccEnabled = prevCctx.mvccEnabled();
-
- if (!mvccEnabled && !dmlInsideTxAllowed && prevCctx.cache().context().tm().inUserTx()) {
- throw new IgniteSQLException("DML statements are not allowed inside a transaction over " +
- "cache(s) with TRANSACTIONAL atomicity mode (change atomicity mode to " +
- "TRANSACTIONAL_SNAPSHOT or disable this error message with system property " +
- "\"IGNITE_ALLOW_DML_INSIDE_TRANSACTION\" [cacheName=" + prevCctx.name() + ']');
- }
- }
- else if (h2tbl.cacheContext().mvccEnabled() != mvccEnabled)
- MvccUtils.throwAtomicityModesMismatchException(prevCctx, h2tbl.cacheContext());
- }
-
+ @Nullable SqlFieldsQuery fieldsQry
+ ) throws IgniteCheckedException {
if (stmt instanceof GridSqlMerge || stmt instanceof GridSqlInsert)
return planForInsert(stmt, loc, idx, mvccEnabled, conn, fieldsQry);
else if (stmt instanceof GridSqlUpdate || stmt instanceof GridSqlDelete)
return planForUpdate(stmt, loc, idx, mvccEnabled, conn, fieldsQry);
else
- throw new IgniteSQLException("Unsupported operation: " + prepared.getSQL(),
+ throw new IgniteSQLException("Unsupported operation: " + stmt.getSQL(),
IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
/**
- * Extract all tables participate at query
- *
- * @param parser Parser related to the query.
- * @return List of tables participate at query.
- * @throws IgniteSQLException in case query contains virtual tables.
- */
- private static List<GridH2Table> extractTablesParticipateAtQuery(GridSqlQueryParser parser) throws IgniteSQLException {
- Collection<?> parserObjects = parser.objectsMap().values();
-
- List<GridH2Table> tbls = new ArrayList<>(parserObjects.size());
-
- // check all involved caches
- for (Object o : parserObjects) {
- if (o instanceof GridSqlMerge)
- o = ((GridSqlMerge)o).into();
- else if (o instanceof GridSqlInsert)
- o = ((GridSqlInsert)o).into();
- else if (o instanceof GridSqlUpdate)
- o = ((GridSqlUpdate)o).target();
- else if (o instanceof GridSqlDelete)
- o = ((GridSqlDelete)o).from();
-
- if (o instanceof GridSqlAlias)
- o = GridSqlAlias.unwrap((GridSqlAst)o);
-
- if (o instanceof GridSqlTable) {
- GridH2Table h2tbl = ((GridSqlTable)o).dataTable();
-
- if (h2tbl == null) { // Check for virtual tables.
- throw new IgniteSQLException("Operation not supported for table '" +
- ((GridSqlTable)o).tableName() + "'", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
- }
-
- tbls.add(h2tbl);
- }
- }
-
- return tbls;
- }
-
- /**
* Prepare update plan for INSERT or MERGE.
*
* @param stmt INSERT or MERGE statement.
@@ -953,9 +875,9 @@ public final class UpdatePlanBuilder {
qry.mapQueries().size() == 1 && !qry.mapQueries().get(0).hasSubQueries(); // One w/o subqueries
if (distributed) {
+ // TODO: This should be done during plan build.
List<Integer> cacheIds = H2Utils.collectCacheIds(idx, CU.cacheId(cacheName), qry.tables());
- H2Utils.collectMvccEnabled(idx, cacheIds);
H2Utils.checkQuery(idx, cacheIds, qry.mvccEnabled(), qry.forUpdate(), qry.tables());
return new DmlDistributedPlanInfo(qry.isReplicatedOnly(), cacheIds);
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index 5b1609d..4d298ff 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -1803,6 +1803,46 @@ public class GridSqlQueryParser {
}
/**
+ * Extract all tables participating in DML statement.
+ *
+ * @return List of tables participate at query.
+ * @throws IgniteSQLException in case query contains virtual tables.
+ */
+ public List<GridH2Table> tablesForDml() throws IgniteSQLException {
+ Collection<?> parserObjects = h2ObjToGridObj.values();
+
+ List<GridH2Table> tbls = new ArrayList<>(parserObjects.size());
+
+ // check all involved caches
+ for (Object o : parserObjects) {
+ if (o instanceof GridSqlMerge)
+ o = ((GridSqlMerge) o).into();
+ else if (o instanceof GridSqlInsert)
+ o = ((GridSqlInsert) o).into();
+ else if (o instanceof GridSqlUpdate)
+ o = ((GridSqlUpdate) o).target();
+ else if (o instanceof GridSqlDelete)
+ o = ((GridSqlDelete) o).from();
+
+ if (o instanceof GridSqlAlias)
+ o = GridSqlAlias.unwrap((GridSqlAst)o);
+
+ if (o instanceof GridSqlTable) {
+ GridH2Table h2tbl = ((GridSqlTable)o).dataTable();
+
+ if (h2tbl == null) { // Check for virtual tables.
+ throw new IgniteSQLException("Operation not supported for table '" +
+ ((GridSqlTable)o).tableName() + "'", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
+ }
+
+ tbls.add(h2tbl);
+ }
+ }
+
+ return tbls;
+ }
+
+ /**
* Parse query.
*
* @param prepared Prepared statement.