You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/10/13 10:27:22 UTC

[6/8] ignite git commit: IGNITE-6024: SQL: Implemented "skipReducerOnUpdate" flag. This closes #2488.

IGNITE-6024: SQL: Implemented "skipReducerOnUpdate" flag. This closes #2488.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ae02a1d3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ae02a1d3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ae02a1d3

Branch: refs/heads/ignite-5932
Commit: ae02a1d3c673f080d6744ff1d3384f9d48a34dea
Parents: 5ec744c
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Fri Oct 13 12:29:53 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Oct 13 12:29:53 2017 +0300

----------------------------------------------------------------------
 .../internal/jdbc2/JdbcConnectionSelfTest.java  |  13 +-
 .../jdbc/suite/IgniteJdbcDriverTestSuite.java   |  11 +
 .../JdbcThinAbstractDmlStatementSelfTest.java   |  14 +-
 .../thin/JdbcThinComplexDmlDdlSelfTest.java     |  10 +-
 ...omplexDmlDdlSkipReducerOnUpdateSelfTest.java |  33 +
 .../jdbc/thin/JdbcThinConnectionSelfTest.java   |  18 +-
 .../thin/JdbcThinInsertStatementSelfTest.java   |   1 -
 ...ertStatementSkipReducerOnUpdateSelfTest.java |  33 +
 ...rgeStatementSkipReducerOnUpdateSelfTest.java |  33 +
 ...ateStatementSkipReducerOnUpdateSelfTest.java |  33 +
 .../ignite/codegen/MessageCodeGenerator.java    |   2 +
 .../org/apache/ignite/IgniteJdbcDriver.java     |   9 +-
 .../org/apache/ignite/IgniteJdbcThinDriver.java |   3 +-
 .../ignite/cache/query/SqlFieldsQuery.java      |   7 +
 .../internal/jdbc/thin/JdbcThinConnection.java  |   4 +-
 .../internal/jdbc/thin/JdbcThinTcpIo.java       |  15 +-
 .../internal/jdbc/thin/JdbcThinUtils.java       |   6 +
 .../internal/jdbc2/JdbcBatchUpdateTask.java     |   3 +-
 .../ignite/internal/jdbc2/JdbcConnection.java   |  14 +-
 .../jdbc2/JdbcQueryMultipleStatementsTask.java  |   3 +-
 .../ignite/internal/jdbc2/JdbcQueryTask.java    |  10 +-
 .../ignite/internal/jdbc2/JdbcQueryTaskV3.java  |  19 +-
 .../ignite/internal/jdbc2/JdbcResultSet.java    |   2 +-
 .../internal/jdbc2/JdbcSqlFieldsQuery.java      | 105 ---
 .../ignite/internal/jdbc2/JdbcStatement.java    |   4 +-
 .../cache/query/GridCacheSqlQuery.java          |  24 +
 .../cache/query/SqlFieldsQueryEx.java           | 158 ++++
 .../odbc/jdbc/JdbcConnectionContext.java        |   7 +-
 .../odbc/jdbc/JdbcRequestHandler.java           |  19 +-
 .../odbc/odbc/OdbcConnectionContext.java        |  13 +-
 .../odbc/odbc/OdbcRequestHandler.java           |  14 +-
 .../resources/META-INF/classnames.properties    |   4 +-
 .../query/h2/DmlStatementsProcessor.java        | 160 ++--
 .../processors/query/h2/H2DmlPlanKey.java       |  21 +-
 .../processors/query/h2/IgniteH2Indexing.java   | 116 ++-
 .../processors/query/h2/UpdateResult.java       |  63 ++
 .../processors/query/h2/dml/UpdatePlan.java     |  64 +-
 .../query/h2/dml/UpdatePlanBuilder.java         | 117 ++-
 .../query/h2/sql/GridSqlQuerySplitter.java      |  33 +
 .../query/h2/twostep/DistributedUpdateRun.java  | 133 ++++
 .../query/h2/twostep/GridMapQueryExecutor.java  | 136 ++++
 .../h2/twostep/GridReduceQueryExecutor.java     | 294 ++++++-
 .../query/h2/twostep/MapNodeResults.java        |  33 +
 .../query/h2/twostep/msg/GridH2DmlRequest.java  | 516 ++++++++++++
 .../query/h2/twostep/msg/GridH2DmlResponse.java | 250 ++++++
 .../twostep/msg/GridH2ValueMessageFactory.java  |   6 +
 ...teSqlSkipReducerOnUpdateDmlFlagSelfTest.java | 783 +++++++++++++++++++
 ...IgniteSqlSkipReducerOnUpdateDmlSelfTest.java | 755 ++++++++++++++++++
 .../IgniteCacheQuerySelfTestSuite.java          |   4 +
 .../cpp/odbc-test/src/configuration_test.cpp    |  25 +-
 .../cpp/odbc-test/src/queries_test.cpp          |   8 +
 .../include/ignite/odbc/config/configuration.h  |  26 +
 .../cpp/odbc/include/ignite/odbc/message.h      |   6 +-
 .../odbc/include/ignite/odbc/protocol_version.h |   1 +
 .../odbc/system/ui/dsn_configuration_window.h   |   4 +
 .../src/system/ui/dsn_configuration_window.cpp  |  20 +
 .../cpp/odbc/src/config/configuration.cpp       |  50 +-
 modules/platforms/cpp/odbc/src/connection.cpp   |   5 +-
 modules/platforms/cpp/odbc/src/dsn_config.cpp   |   4 +
 modules/platforms/cpp/odbc/src/message.cpp      |  12 +-
 .../platforms/cpp/odbc/src/protocol_version.cpp |   6 +-
 61 files changed, 3999 insertions(+), 296 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java
index aeb7c76..35d0fba 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java
@@ -31,7 +31,6 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.IgniteJdbcDriver.CFG_URL_PREFIX;
 
@@ -315,6 +314,7 @@ public class JdbcConnectionSelfTest extends GridCommonAbstractTest {
             assertFalse(((JdbcConnection)conn).isDistributedJoins());
             assertFalse(((JdbcConnection)conn).isCollocatedQuery());
             assertFalse(((JdbcConnection)conn).isLazy());
+            assertFalse(((JdbcConnection)conn).skipReducerOnUpdate());
         }
 
         try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "distributedJoins=true@"
@@ -323,6 +323,7 @@ public class JdbcConnectionSelfTest extends GridCommonAbstractTest {
             assertTrue(((JdbcConnection)conn).isDistributedJoins());
             assertFalse(((JdbcConnection)conn).isCollocatedQuery());
             assertFalse(((JdbcConnection)conn).isLazy());
+            assertFalse(((JdbcConnection)conn).skipReducerOnUpdate());
         }
 
         try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "collocated=true@"
@@ -331,6 +332,7 @@ public class JdbcConnectionSelfTest extends GridCommonAbstractTest {
             assertFalse(((JdbcConnection)conn).isDistributedJoins());
             assertTrue(((JdbcConnection)conn).isCollocatedQuery());
             assertFalse(((JdbcConnection)conn).isLazy());
+            assertFalse(((JdbcConnection)conn).skipReducerOnUpdate());
         }
 
         try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "lazy=true@" + configURL())) {
@@ -338,6 +340,15 @@ public class JdbcConnectionSelfTest extends GridCommonAbstractTest {
             assertFalse(((JdbcConnection)conn).isDistributedJoins());
             assertFalse(((JdbcConnection)conn).isCollocatedQuery());
             assertTrue(((JdbcConnection)conn).isLazy());
+            assertFalse(((JdbcConnection)conn).skipReducerOnUpdate());
+        }
+        try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "skipReducerOnUpdate=true@"
+            + configURL())) {
+            assertFalse(((JdbcConnection)conn).isEnforceJoinOrder());
+            assertFalse(((JdbcConnection)conn).isDistributedJoins());
+            assertFalse(((JdbcConnection)conn).isCollocatedQuery());
+            assertFalse(((JdbcConnection)conn).isLazy());
+            assertTrue(((JdbcConnection)conn).skipReducerOnUpdate());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
index 1ae2427..bec388a 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
@@ -58,6 +58,10 @@ import org.apache.ignite.jdbc.thin.JdbcThinSchemaCaseTest;
 import org.apache.ignite.jdbc.thin.JdbcThinSelectAfterAlterTable;
 import org.apache.ignite.jdbc.thin.JdbcThinStatementSelfTest;
 import org.apache.ignite.jdbc.thin.JdbcThinUpdateStatementSelfTest;
+import org.apache.ignite.jdbc.thin.JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest;
+import org.apache.ignite.jdbc.thin.JdbcThinInsertStatementSkipReducerOnUpdateSelfTest;
+import org.apache.ignite.jdbc.thin.JdbcThinMergeStatementSkipReducerOnUpdateSelfTest;
+import org.apache.ignite.jdbc.thin.JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest;
 
 /**
  * JDBC driver test suite.
@@ -152,6 +156,13 @@ public class IgniteJdbcDriverTestSuite extends TestSuite {
 
         suite.addTest(new TestSuite(JdbcThinSelectAfterAlterTable.class));
 
+        // Update on server
+        suite.addTest(new TestSuite(JdbcThinInsertStatementSkipReducerOnUpdateSelfTest.class));
+        suite.addTest(new TestSuite(JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest.class));
+        suite.addTest(new TestSuite(JdbcThinMergeStatementSkipReducerOnUpdateSelfTest.class));
+        suite.addTest(new TestSuite(JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest.class));
+
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
index afe5e2e..69435da 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinAbstractDmlStatementSelfTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.jdbc.thin;
 import java.io.Serializable;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.SQLException;
 import java.util.Collections;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
@@ -42,9 +43,6 @@ public abstract class JdbcThinAbstractDmlStatementSelfTest extends JdbcThinAbstr
     /** IP finder. */
     private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
 
-    /** URL. */
-    private static final String URL = "jdbc:ignite:thin://127.0.0.1/";
-
     /** SQL SELECT query for verification. */
     static final String SQL_SELECT = "select _key, id, firstName, lastName, age from Person";
 
@@ -67,7 +65,7 @@ public abstract class JdbcThinAbstractDmlStatementSelfTest extends JdbcThinAbstr
     @Override protected void beforeTest() throws Exception {
         ignite(0).getOrCreateCache(cacheConfig());
 
-        conn = DriverManager.getConnection(URL);
+        conn = createConnection();
 
         conn.setSchema('"' + DEFAULT_CACHE_NAME + '"');
     }
@@ -81,6 +79,14 @@ public abstract class JdbcThinAbstractDmlStatementSelfTest extends JdbcThinAbstr
         assertTrue(conn.isClosed());
     }
 
+    /**
+     * @return JDBC connection.
+     * @throws SQLException On error.
+     */
+    protected Connection createConnection() throws SQLException {
+        return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/");
+    }
+
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
         return getConfiguration0(igniteInstanceName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSelfTest.java
index 0760107..d4e03bc 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSelfTest.java
@@ -93,6 +93,14 @@ public class JdbcThinComplexDmlDdlSelfTest extends GridCommonAbstractTest {
         return cfg;
     }
 
+    /**
+     * @return JDBC connection.
+     * @throws SQLException On error.
+     */
+    protected Connection createConnection() throws SQLException {
+        return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1");
+    }
+
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
@@ -109,7 +117,7 @@ public class JdbcThinComplexDmlDdlSelfTest extends GridCommonAbstractTest {
     @Override protected void beforeTest() throws Exception {
         super.beforeTest();
 
-        conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1");
+        conn = createConnection();
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest.java
new file mode 100644
index 0000000..7ae6479
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.jdbc.thin;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import org.apache.ignite.jdbc.thin.JdbcThinComplexDmlDdlSelfTest;
+
+/**
+ * Base class for complex SQL tests based on JDBC driver.
+ */
+public class JdbcThinComplexDmlDdlSkipReducerOnUpdateSelfTest extends JdbcThinComplexDmlDdlSelfTest {
+    /** {@inheritDoc} */
+    @Override protected Connection createConnection() throws SQLException {
+        return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?skipReducerOnUpdate=true");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
index fbbec0d..7f67136 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
@@ -187,6 +187,7 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
             assertFalse(io(conn).collocated());
             assertFalse(io(conn).replicatedOnly());
             assertFalse(io(conn).lazy());
+            assertFalse(io(conn).skipReducerOnUpdate());
         }
 
         try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?distributedJoins=true")) {
@@ -195,6 +196,7 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
             assertFalse(io(conn).collocated());
             assertFalse(io(conn).replicatedOnly());
             assertFalse(io(conn).lazy());
+            assertFalse(io(conn).skipReducerOnUpdate());
         }
 
         try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?enforceJoinOrder=true")) {
@@ -203,6 +205,7 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
             assertFalse(io(conn).collocated());
             assertFalse(io(conn).replicatedOnly());
             assertFalse(io(conn).lazy());
+            assertFalse(io(conn).skipReducerOnUpdate());
         }
 
         try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?collocated=true")) {
@@ -211,6 +214,7 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
             assertTrue(io(conn).collocated());
             assertFalse(io(conn).replicatedOnly());
             assertFalse(io(conn).lazy());
+            assertFalse(io(conn).skipReducerOnUpdate());
         }
 
         try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?replicatedOnly=true")) {
@@ -219,6 +223,7 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
             assertFalse(io(conn).collocated());
             assertTrue(io(conn).replicatedOnly());
             assertFalse(io(conn).lazy());
+            assertFalse(io(conn).skipReducerOnUpdate());
         }
 
         try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?lazy=true")) {
@@ -227,15 +232,26 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest {
             assertFalse(io(conn).collocated());
             assertFalse(io(conn).replicatedOnly());
             assertTrue(io(conn).lazy());
+            assertFalse(io(conn).skipReducerOnUpdate());
+        }
+
+        try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?skipReducerOnUpdate=true")) {
+            assertFalse(io(conn).distributedJoins());
+            assertFalse(io(conn).enforceJoinOrder());
+            assertFalse(io(conn).collocated());
+            assertFalse(io(conn).replicatedOnly());
+            assertFalse(io(conn).lazy());
+            assertTrue(io(conn).skipReducerOnUpdate());
         }
 
         try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?distributedJoins=true&" +
-            "enforceJoinOrder=true&collocated=true&replicatedOnly=true&lazy=true")) {
+            "enforceJoinOrder=true&collocated=true&replicatedOnly=true&lazy=true&skipReducerOnUpdate=true")) {
             assertTrue(io(conn).distributedJoins());
             assertTrue(io(conn).enforceJoinOrder());
             assertTrue(io(conn).collocated());
             assertTrue(io(conn).replicatedOnly());
             assertTrue(io(conn).lazy());
+            assertTrue(io(conn).skipReducerOnUpdate());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java
index 8ab5760..bf55da0 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java
@@ -24,7 +24,6 @@ import java.sql.Statement;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.concurrent.Callable;
-import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.testframework.GridTestUtils;
 
 /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSkipReducerOnUpdateSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSkipReducerOnUpdateSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSkipReducerOnUpdateSelfTest.java
new file mode 100644
index 0000000..d99639f
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSkipReducerOnUpdateSelfTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.jdbc.thin;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import org.apache.ignite.jdbc.thin.JdbcThinInsertStatementSelfTest;
+
+/**
+ * Statement test.
+ */
+public class JdbcThinInsertStatementSkipReducerOnUpdateSelfTest extends JdbcThinInsertStatementSelfTest {
+    /** {@inheritDoc} */
+    @Override protected Connection createConnection() throws SQLException {
+        return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?skipReducerOnUpdate=true");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMergeStatementSkipReducerOnUpdateSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMergeStatementSkipReducerOnUpdateSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMergeStatementSkipReducerOnUpdateSelfTest.java
new file mode 100644
index 0000000..0832fb7
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinMergeStatementSkipReducerOnUpdateSelfTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.jdbc.thin;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import org.apache.ignite.jdbc.thin.JdbcThinMergeStatementSelfTest;
+
+/**
+ * MERGE statement test.
+ */
+public class JdbcThinMergeStatementSkipReducerOnUpdateSelfTest extends JdbcThinMergeStatementSelfTest {
+    /** {@inheritDoc} */
+    @Override protected Connection createConnection() throws SQLException {
+        return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?skipReducerOnUpdate=true");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest.java
new file mode 100644
index 0000000..475a77f
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.jdbc.thin;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import org.apache.ignite.jdbc.thin.JdbcThinUpdateStatementSelfTest;
+
+/**
+ *
+ */
+public class JdbcThinUpdateStatementSkipReducerOnUpdateSelfTest extends JdbcThinUpdateStatementSelfTest {
+    /** {@inheritDoc} */
+    @Override protected Connection createConnection() throws SQLException {
+        return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1?skipReducerOnUpdate=true");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
----------------------------------------------------------------------
diff --git a/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
index 99ec08a..3ea0c81 100644
--- a/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
+++ b/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
@@ -235,6 +235,8 @@ public class MessageCodeGenerator {
 //        gen.generateAndWrite(GridH2RowMessage.class);
 //        gen.generateAndWrite(GridCacheVersion.class);
 //        gen.generateAndWrite(GridCacheVersionEx.class);
+//        gen.generateAndWrite(GridH2DmlRequest.class);
+//        gen.generateAndWrite(GridH2DmlResponse.class);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
index b03e387..ea9b7f8 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcDriver.java
@@ -334,6 +334,9 @@ public class IgniteJdbcDriver implements Driver {
     /** Allow queries with multiple statements. */
     private static final String PARAM_MULTIPLE_STMTS = "multipleStatementsAllowed";
 
+    /** Skip reducer on update property name. */
+    private static final String PARAM_SKIP_REDUCER_ON_UPDATE = "skipReducerOnUpdate";
+
     /** Hostname property name. */
     public static final String PROP_HOST = PROP_PREFIX + "host";
 
@@ -382,6 +385,9 @@ public class IgniteJdbcDriver implements Driver {
     /** Allow query with multiple statements. */
     public static final String PROP_MULTIPLE_STMTS = PROP_PREFIX + PARAM_MULTIPLE_STMTS;
 
+    /** Skip reducer on update update property name. */
+    public static final String PROP_SKIP_REDUCER_ON_UPDATE = PROP_PREFIX + PARAM_SKIP_REDUCER_ON_UPDATE;
+
     /** Cache name property name. */
     public static final String PROP_CFG = PROP_PREFIX + "cfg";
 
@@ -454,7 +460,8 @@ public class IgniteJdbcDriver implements Driver {
             new JdbcDriverPropertyInfo("Enforce Join Order", info.getProperty(JdbcThinUtils.PROP_ENFORCE_JOIN_ORDER), ""),
             new JdbcDriverPropertyInfo("Lazy query execution", info.getProperty(JdbcThinUtils.PROP_LAZY), ""),
             new JdbcDriverPropertyInfo("Transactions Allowed", info.getProperty(PROP_TX_ALLOWED), ""),
-            new JdbcDriverPropertyInfo("Queries with multiple statements allowed", info.getProperty(PROP_MULTIPLE_STMTS), "")
+            new JdbcDriverPropertyInfo("Queries with multiple statements allowed", info.getProperty(PROP_MULTIPLE_STMTS), ""),
+            new JdbcDriverPropertyInfo("Skip reducer on update", info.getProperty(PROP_SKIP_REDUCER_ON_UPDATE), "")
         );
 
         if (info.getProperty(PROP_CFG) != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDriver.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDriver.java b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDriver.java
index 8085ed4..a313f92 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDriver.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteJdbcThinDriver.java
@@ -186,7 +186,8 @@ public class IgniteJdbcThinDriver implements Driver {
             new JdbcDriverPropertyInfo("Enforce Join Order", info.getProperty(JdbcThinUtils.PROP_ENFORCE_JOIN_ORDER), ""),
             new JdbcDriverPropertyInfo("Collocated", info.getProperty(JdbcThinUtils.PROP_COLLOCATED), ""),
             new JdbcDriverPropertyInfo("Replicated only", info.getProperty(JdbcThinUtils.PROP_REPLICATED_ONLY), ""),
-            new JdbcDriverPropertyInfo("Lazy query execution flag", info.getProperty(JdbcThinUtils.PROP_LAZY),"")
+            new JdbcDriverPropertyInfo("Lazy query execution flag", info.getProperty(JdbcThinUtils.PROP_LAZY),""),
+            new JdbcDriverPropertyInfo("Skip reducer on update", info.getProperty(JdbcThinUtils.PROP_SKIP_REDUCER_ON_UPDATE),"")
         );
 
         return props.toArray(new DriverPropertyInfo[0]);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
index 2d128d1..4e12b8c 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
@@ -369,6 +369,13 @@ public class SqlFieldsQuery extends Query<List<?>> {
         return this;
     }
 
+    /**
+     * @return Copy of this query.
+     */
+    public SqlFieldsQuery copy() {
+        return new SqlFieldsQuery(this);
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(SqlFieldsQuery.class, this);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
index 5afed4e..57b25e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
@@ -62,6 +62,7 @@ import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_REPLICATED
 import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_SOCK_RCV_BUF;
 import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_SOCK_SND_BUF;
 import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_TCP_NO_DELAY;
+import static org.apache.ignite.internal.jdbc.thin.JdbcThinUtils.PROP_SKIP_REDUCER_ON_UPDATE;
 
 /**
  * JDBC connection implementation.
@@ -136,10 +137,11 @@ public class JdbcThinConnection implements Connection {
         int sockRcvBuf = extractIntNonNegative(props, PROP_SOCK_RCV_BUF, 0);
 
         boolean tcpNoDelay  = extractBoolean(props, PROP_TCP_NO_DELAY, true);
+        boolean skipReducerOnUpdate  = extractBoolean(props, PROP_SKIP_REDUCER_ON_UPDATE, false);
 
         try {
             cliIo = new JdbcThinTcpIo(host, port, distributedJoins, enforceJoinOrder, collocated, replicatedOnly,
-                autoCloseServerCursor, lazyExec, sockSndBuf, sockRcvBuf, tcpNoDelay);
+                autoCloseServerCursor, lazyExec, sockSndBuf, sockRcvBuf, tcpNoDelay, skipReducerOnUpdate);
 
             cliIo.start();
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index 9e12fbf..0670fb1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -100,6 +100,9 @@ public class JdbcThinTcpIo {
     /** Flag to automatically close server cursor. */
     private final boolean autoCloseServerCursor;
 
+    /** Executes update queries on server nodes. */
+    private final boolean skipReducerOnUpdate;
+
     /** Socket send buffer. */
     private final int sockSndBuf;
 
@@ -138,10 +141,11 @@ public class JdbcThinTcpIo {
      * @param sockSndBuf Socket send buffer.
      * @param sockRcvBuf Socket receive buffer.
      * @param tcpNoDelay TCP no delay flag.
+     * @param skipReducerOnUpdate Executes update queries on ignite server nodes.
      */
     JdbcThinTcpIo(String host, int port, boolean distributedJoins, boolean enforceJoinOrder, boolean collocated,
         boolean replicatedOnly, boolean autoCloseServerCursor, boolean lazy, int sockSndBuf, int sockRcvBuf,
-        boolean tcpNoDelay) {
+        boolean tcpNoDelay, boolean skipReducerOnUpdate) {
         this.host = host;
         this.port = port;
         this.distributedJoins = distributedJoins;
@@ -153,6 +157,7 @@ public class JdbcThinTcpIo {
         this.sockSndBuf = sockSndBuf;
         this.sockRcvBuf = sockRcvBuf;
         this.tcpNoDelay = tcpNoDelay;
+        this.skipReducerOnUpdate = skipReducerOnUpdate;
     }
 
     /**
@@ -211,6 +216,7 @@ public class JdbcThinTcpIo {
         writer.writeBoolean(replicatedOnly);
         writer.writeBoolean(autoCloseServerCursor);
         writer.writeBoolean(lazy);
+        writer.writeBoolean(skipReducerOnUpdate);
 
         send(writer.array());
 
@@ -491,4 +497,11 @@ public class JdbcThinTcpIo {
     public boolean lazy() {
         return lazy;
     }
+
+    /**
+     * @return Server side update flag.
+     */
+    public boolean skipReducerOnUpdate() {
+        return skipReducerOnUpdate;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinUtils.java
index 52b3abc..c9bf61c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinUtils.java
@@ -81,6 +81,9 @@ public class JdbcThinUtils {
     /** Parameter: Automatically close server cursor. */
     public static final String PARAM_AUTO_CLOSE_SERVER_CURSOR = "autoCloseServerCursor";
 
+    /** Parameter: execute update query in distributed mode on ignite server nodes. */
+    public static final String PARAM_SKIP_REDUCER_ON_UPDATE = "skipReducerOnUpdate";
+
     /** Distributed joins property name. */
     public static final String PROP_DISTRIBUTED_JOINS = PROP_PREFIX + PARAM_DISTRIBUTED_JOINS;
 
@@ -108,6 +111,9 @@ public class JdbcThinUtils {
     /** Automatically close server cursor. */
     public static final String PROP_AUTO_CLOSE_SERVER_CURSORS = PROP_PREFIX + PARAM_AUTO_CLOSE_SERVER_CURSOR;
 
+    /** Executes update queries on ignite server nodes in distributed mode. */
+    public static final String PROP_SKIP_REDUCER_ON_UPDATE = PROP_PREFIX + PARAM_SKIP_REDUCER_ON_UPDATE;
+
     /** Default port. */
     public static final int DFLT_PORT = ClientConnectorConfiguration.DFLT_PORT;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBatchUpdateTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBatchUpdateTask.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBatchUpdateTask.java
index e4916f7..774f922 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBatchUpdateTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBatchUpdateTask.java
@@ -29,6 +29,7 @@ import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
+import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.resources.IgniteInstanceResource;
@@ -162,7 +163,7 @@ class JdbcBatchUpdateTask implements IgniteCallable<int[]> {
      * @throws SQLException If failed.
      */
     private Integer doSingleUpdate(IgniteCache<?, ?> cache, String sqlText, List<Object> args) throws SQLException {
-        SqlFieldsQuery qry = new JdbcSqlFieldsQuery(sqlText, false);
+        SqlFieldsQuery qry = new SqlFieldsQueryEx(sqlText, false);
 
         qry.setPageSize(fetchSize);
         qry.setLocal(locQry);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
index ccc09ec..29cb6a1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
@@ -82,12 +82,13 @@ import static org.apache.ignite.IgniteJdbcDriver.PROP_LAZY;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_LOCAL;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_MULTIPLE_STMTS;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_NODE_ID;
-import static org.apache.ignite.IgniteJdbcDriver.PROP_TX_ALLOWED;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_STREAMING;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_STREAMING_ALLOW_OVERWRITE;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_STREAMING_FLUSH_FREQ;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_STREAMING_PER_NODE_BUF_SIZE;
 import static org.apache.ignite.IgniteJdbcDriver.PROP_STREAMING_PER_NODE_PAR_OPS;
+import static org.apache.ignite.IgniteJdbcDriver.PROP_TX_ALLOWED;
+import static org.apache.ignite.IgniteJdbcDriver.PROP_SKIP_REDUCER_ON_UPDATE;
 import static org.apache.ignite.internal.jdbc2.JdbcUtils.convertToSqlException;
 import static org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode.createJdbcSqlException;
 
@@ -168,6 +169,9 @@ public class JdbcConnection implements Connection {
     /** Allow queries with multiple statements. */
     private final boolean multipleStmts;
 
+    /** Skip reducer on update flag. */
+    private final boolean skipReducerOnUpdate;
+
     /** Statements. */
     final Set<JdbcStatement> statements = new HashSet<>();
 
@@ -209,6 +213,7 @@ public class JdbcConnection implements Connection {
         streamNodeParOps = Integer.parseInt(props.getProperty(PROP_STREAMING_PER_NODE_PAR_OPS, "0"));
 
         multipleStmts = Boolean.parseBoolean(props.getProperty(PROP_MULTIPLE_STMTS));
+        skipReducerOnUpdate = Boolean.parseBoolean(props.getProperty(PROP_SKIP_REDUCER_ON_UPDATE));
 
         String nodeIdProp = props.getProperty(PROP_NODE_ID);
 
@@ -854,6 +859,13 @@ public class JdbcConnection implements Connection {
     }
 
     /**
+     * @return {@code true} if update on server is enabled, {@code false} otherwise.
+     */
+    boolean skipReducerOnUpdate() {
+        return skipReducerOnUpdate;
+    }
+
+    /**
      * @return Local query flag.
      */
     boolean isLocalQuery() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
index bf7c24e..f907525 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryMultipleStatementsTask.java
@@ -27,6 +27,7 @@ import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
+import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.resources.IgniteInstanceResource;
@@ -109,7 +110,7 @@ class JdbcQueryMultipleStatementsTask implements IgniteCallable<List<JdbcStateme
 
     /** {@inheritDoc} */
     @Override public List<JdbcStatementResultInfo> call() throws Exception {
-        SqlFieldsQuery qry = (isQry != null ? new JdbcSqlFieldsQuery(sql, isQry) : new SqlFieldsQuery(sql))
+        SqlFieldsQuery qry = (isQry != null ? new SqlFieldsQueryEx(sql, isQry) : new SqlFieldsQuery(sql))
             .setArgs(args);
 
         qry.setPageSize(fetchSize);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
index ecbfb71..aa9f009 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTask.java
@@ -36,6 +36,7 @@ import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
+import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.util.typedef.CAX;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -156,7 +157,7 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTaskResult> {
                     throw new SQLException("Cache not found [cacheName=" + cacheName + ']');
             }
 
-            SqlFieldsQuery qry = (isQry != null ? new JdbcSqlFieldsQuery(sql, isQry) : new SqlFieldsQuery(sql))
+            SqlFieldsQuery qry = (isQry != null ? new SqlFieldsQueryEx(sql, isQry) : new SqlFieldsQuery(sql))
                 .setArgs(args);
 
             qry.setPageSize(fetchSize);
@@ -241,6 +242,13 @@ class JdbcQueryTask implements IgniteCallable<JdbcQueryTaskResult> {
     }
 
     /**
+     * @return Flag to update enable server side updates.
+     */
+    protected boolean skipReducerOnUpdate() {
+        return false;
+    }
+
+    /**
      * Schedules removal of stored cursor in case of remote query execution.
      *
      * @param uuid Cursor UUID.

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
index cb2d452..f002d87 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcQueryTaskV3.java
@@ -30,6 +30,9 @@ class JdbcQueryTaskV3 extends JdbcQueryTaskV2 {
     /** Update metadata on demand flag. */
     private final boolean updateMeta;
 
+    /** Update metadata on demand flag. */
+    private final boolean skipReducerOnUpdate;
+
     /**
      * @param ignite Ignite.
      * @param cacheName Cache name.
@@ -46,14 +49,16 @@ class JdbcQueryTaskV3 extends JdbcQueryTaskV2 {
      * @param enforceJoinOrder Enforce joins order flag.
      * @param lazy Lazy query execution flag.
      * @param updateMeta Update metadata on demand.
+     * @param skipReducerOnUpdate Flkag to enable server side updates.
      */
     public JdbcQueryTaskV3(Ignite ignite, String cacheName, String schemaName, String sql, Boolean isQry, boolean loc,
         Object[] args, int fetchSize, UUID uuid, boolean locQry, boolean collocatedQry, boolean distributedJoins,
-        boolean enforceJoinOrder, boolean lazy, boolean updateMeta) {
+        boolean enforceJoinOrder, boolean lazy, boolean updateMeta, boolean skipReducerOnUpdate) {
         super(ignite, cacheName, schemaName, sql, isQry, loc, args, fetchSize, uuid, locQry,
             collocatedQry, distributedJoins, enforceJoinOrder, lazy);
 
         this.updateMeta = updateMeta;
+        this.skipReducerOnUpdate = skipReducerOnUpdate;
     }
 
     /** {@inheritDoc} */
@@ -61,6 +66,11 @@ class JdbcQueryTaskV3 extends JdbcQueryTaskV2 {
         return updateMeta;
     }
 
+    /** {@inheritDoc} */
+    @Override protected boolean skipReducerOnUpdate() {
+        return skipReducerOnUpdate;
+    }
+
     /**
      * @param ignite Ignite.
      * @param cacheName Cache name.
@@ -77,16 +87,17 @@ class JdbcQueryTaskV3 extends JdbcQueryTaskV2 {
      * @param enforceJoinOrder Enforce joins order flag.
      * @param lazy Lazy query execution flag.
      * @param updateMeta Update metadata on demand.
+     * @param skipReducerOnUpdate Update on server flag.
      * @return Appropriate task JdbcQueryTask or JdbcQueryTaskV2.
      */
     public static JdbcQueryTask createTask(Ignite ignite, String cacheName, String schemaName, String sql,
         Boolean isQry, boolean loc, Object[] args, int fetchSize, UUID uuid, boolean locQry,
         boolean collocatedQry, boolean distributedJoins,
-        boolean enforceJoinOrder, boolean lazy, boolean updateMeta) {
+        boolean enforceJoinOrder, boolean lazy, boolean updateMeta, boolean skipReducerOnUpdate) {
 
-        if (updateMeta)
+        if (updateMeta || skipReducerOnUpdate)
             return new JdbcQueryTaskV3(ignite, cacheName, schemaName, sql, isQry, loc, args, fetchSize,
-                uuid, locQry, collocatedQry, distributedJoins, enforceJoinOrder, lazy, true);
+                uuid, locQry, collocatedQry, distributedJoins, enforceJoinOrder, lazy, updateMeta, skipReducerOnUpdate);
         else
             return JdbcQueryTaskV2.createTask(ignite, cacheName, schemaName, sql, isQry, loc, args, fetchSize,
                 uuid, locQry, collocatedQry, distributedJoins, enforceJoinOrder, lazy);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
index 69d4252..e2ff5d8 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
@@ -205,7 +205,7 @@ public class JdbcResultSet implements ResultSet {
         // Connections from new clients send queries with new tasks, so we have to continue in the same manner
         JdbcQueryTask qryTask = JdbcQueryTaskV3.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
             null,true, loc, null, fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
-            conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy(), updateMetadata);
+            conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy(), updateMetadata, false);
 
         try {
             JdbcQueryTaskResult res =

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
deleted file mode 100644
index d8b9a26..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcSqlFieldsQuery.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.jdbc2;
-
-import java.util.concurrent.TimeUnit;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-
-/**
- * {@link SqlFieldsQuery} with JDBC flavor - it has additional flag indicating whether JDBC driver expects
- * this query to return a result set or an update counter. This class is not intended for use outside JDBC driver.
- */
-public final class JdbcSqlFieldsQuery extends SqlFieldsQuery {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Flag set by JDBC driver to enforce checks for correct operation type. */
-    private final boolean isQry;
-
-    /**
-     * @param sql SQL query.
-     * @param isQry Flag indicating whether this object denotes a query or an update operation.
-     */
-    public JdbcSqlFieldsQuery(String sql, boolean isQry) {
-        super(sql);
-        this.isQry = isQry;
-    }
-
-    /**
-     * @return Flag indicating whether this object denotes a query or an update operation..
-     */
-    public boolean isQuery() {
-        return isQry;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setSql(String sql) {
-        super.setSql(sql);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setArgs(Object... args) {
-        super.setArgs(args);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setTimeout(int timeout, TimeUnit timeUnit) {
-        super.setTimeout(timeout, timeUnit);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setCollocated(boolean collocated) {
-        super.setCollocated(collocated);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setEnforceJoinOrder(boolean enforceJoinOrder) {
-        super.setEnforceJoinOrder(enforceJoinOrder);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setDistributedJoins(boolean distributedJoins) {
-        super.setDistributedJoins(distributedJoins);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setPageSize(int pageSize) {
-        super.setPageSize(pageSize);
-
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdbcSqlFieldsQuery setLocal(boolean loc) {
-        super.setLocal(loc);
-
-        return this;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
index acac123..2498456 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement.java
@@ -161,9 +161,9 @@ public class JdbcStatement implements Statement {
             else
                 isQuery = true;
 
-        JdbcQueryTask qryTask = JdbcQueryTaskV2.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
+        JdbcQueryTask qryTask = JdbcQueryTaskV3.createTask(loc ? ignite : null, conn.cacheName(), conn.schemaName(),
             sql, isQuery, loc, getArgs(), fetchSize, uuid, conn.isLocalQuery(), conn.isCollocatedQuery(),
-            conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy());
+            conn.isDistributedJoins(), conn.isEnforceJoinOrder(), conn.isLazy(), false, conn.skipReducerOnUpdate());
 
         try {
             JdbcQueryTaskResult qryRes =

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
index d3746f3..f38c5b2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
@@ -74,6 +74,11 @@ public class GridCacheSqlQuery implements Message {
     @GridDirectTransient
     private transient Object[] derivedPartitions;
 
+    /** Flag indicating that query contains sub-queries. */
+    @GridToStringInclude
+    @GridDirectTransient
+    private transient boolean hasSubQries;
+
     /**
      * For {@link Message}.
      */
@@ -259,6 +264,7 @@ public class GridCacheSqlQuery implements Message {
         cp.sort = sort;
         cp.partitioned = partitioned;
         cp.derivedPartitions = derivedPartitions;
+        cp.hasSubQries = hasSubQries;
 
         return cp;
     }
@@ -347,4 +353,22 @@ public class GridCacheSqlQuery implements Message {
 
         return this;
     }
+
+    /**
+     * @return {@code true} if query contains sub-queries.
+     */
+    public boolean hasSubQueries() {
+        return hasSubQries;
+    }
+
+    /**
+     * @param hasSubQries Flag indicating that query contains sub-queries.
+     *
+     * @return {@code this}.
+     */
+    public GridCacheSqlQuery hasSubQueries(boolean hasSubQries) {
+        this.hasSubQries = hasSubQries;
+
+        return this;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/SqlFieldsQueryEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/SqlFieldsQueryEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/SqlFieldsQueryEx.java
new file mode 100644
index 0000000..c5f786e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/SqlFieldsQueryEx.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+
+/**
+ * {@link SqlFieldsQuery} with experimental and internal features.
+ */
+public final class SqlFieldsQueryEx extends SqlFieldsQuery {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Flag to enforce checks for correct operation type. */
+    private final Boolean isQry;
+
+    /** Whether server side DML should be enabled. */
+    private boolean skipReducerOnUpdate;
+
+    /**
+     * @param sql SQL query.
+     * @param isQry Flag indicating whether this object denotes a query or an update operation.
+     */
+    public SqlFieldsQueryEx(String sql, Boolean isQry) {
+        super(sql);
+        this.isQry = isQry;
+    }
+
+    /**
+     * @param qry SQL query.
+     */
+    private SqlFieldsQueryEx(SqlFieldsQueryEx qry) {
+        super(qry);
+
+        this.isQry = qry.isQry;
+        this.skipReducerOnUpdate = qry.skipReducerOnUpdate;
+    }
+
+    /**
+     * @return Flag indicating whether this object denotes a query or an update operation.
+     */
+    public Boolean isQuery() {
+        return isQry;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setSql(String sql) {
+        super.setSql(sql);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setArgs(Object... args) {
+        super.setArgs(args);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setTimeout(int timeout, TimeUnit timeUnit) {
+        super.setTimeout(timeout, timeUnit);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setCollocated(boolean collocated) {
+        super.setCollocated(collocated);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setEnforceJoinOrder(boolean enforceJoinOrder) {
+        super.setEnforceJoinOrder(enforceJoinOrder);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setDistributedJoins(boolean distributedJoins) {
+        super.setDistributedJoins(distributedJoins);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setPageSize(int pageSize) {
+        super.setPageSize(pageSize);
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQueryEx setLocal(boolean loc) {
+        super.setLocal(loc);
+
+        return this;
+    }
+
+    /**
+     * Sets server side update flag.
+     * <p>
+     * By default, when processing DML command, Ignite first fetches all affected intermediate rows for analysis to the
+     * node which initiated the query and only then forms batches of updated values to be sent to remote nodes.
+     * For simple DML commands (that however affect great deal of rows) such approach may be an overkill in terms of
+     * network delays and memory usage on initiating node. Use this flag as hint for Ignite to do all intermediate rows
+     * analysis and updates in place on corresponding remote data nodes.
+     * <p>
+     * There are limitations to what DML command can be optimized this way. The command containing LIMIT, OFFSET,
+     * DISTINCT, ORDER BY, GROUP BY, sub-query or UNION will be processed the usual way despite this flag setting.
+     * <p>
+     * Defaults to {@code false}, meaning that intermediate results will be fetched to initiating node first.
+     * Only affects DML commands. Ignored when {@link #isLocal()} is {@code true}.
+     * Note that when set to {@code true}, the query may fail in the case of even single node failure.
+     *
+     * @param skipReducerOnUpdate Server side update flag.
+     * @return {@code this} For chaining.
+     */
+    public SqlFieldsQuery setSkipReducerOnUpdate(boolean skipReducerOnUpdate) {
+        this.skipReducerOnUpdate = skipReducerOnUpdate;
+
+        return this;
+    }
+
+    /**
+     * Gets server side update flag.
+     * <p>
+     * See {@link #setSkipReducerOnUpdate(boolean)} for more information.
+     *
+     * @return Server side update flag.
+     */
+    public boolean isSkipReducerOnUpdate() {
+        return skipReducerOnUpdate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public SqlFieldsQuery copy() {
+        return new SqlFieldsQueryEx(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
index a6a7aa5..7b40466 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java
@@ -104,8 +104,13 @@ public class JdbcConnectionContext implements ClientListenerConnectionContext {
         if (ver.compareTo(VER_2_1_5) >= 0)
             lazyExec = reader.readBoolean();
 
+        boolean skipReducerOnUpdate = false;
+
+        if (ver.compareTo(VER_2_3_0) >= 0)
+            skipReducerOnUpdate = reader.readBoolean();
+
         handler = new JdbcRequestHandler(ctx, busyLock, maxCursors, distributedJoins, enforceJoinOrder,
-            collocated, replicatedOnly, autoCloseCursors, lazyExec, ver);
+            collocated, replicatedOnly, autoCloseCursors, lazyExec, skipReducerOnUpdate, ver);
 
         parser = new JdbcMessageParser(ctx);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index 166402f..e3b6f5b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -35,7 +35,7 @@ import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteVersionUtils;
 import org.apache.ignite.internal.binary.BinaryWriterExImpl;
-import org.apache.ignite.internal.jdbc2.JdbcSqlFieldsQuery;
+import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion;
@@ -103,6 +103,9 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
     /** Lazy query execution flag. */
     private final boolean lazy;
 
+    /** Skip reducer on update flag. */
+    private final boolean skipReducerOnUpdate;
+
     /** Automatic close of cursors. */
     private final boolean autoCloseCursors;
 
@@ -121,11 +124,13 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
      * @param replicatedOnly Replicated only flag.
      * @param autoCloseCursors Flag to automatically close server cursors.
      * @param lazy Lazy query execution flag.
+     * @param skipReducerOnUpdate Skip reducer on update flag.
      * @param protocolVer Protocol version.
      */
     public JdbcRequestHandler(GridKernalContext ctx, GridSpinBusyLock busyLock, int maxCursors,
         boolean distributedJoins, boolean enforceJoinOrder, boolean collocated, boolean replicatedOnly,
-        boolean autoCloseCursors, boolean lazy, ClientListenerProtocolVersion protocolVer) {
+        boolean autoCloseCursors, boolean lazy, boolean skipReducerOnUpdate,
+        ClientListenerProtocolVersion protocolVer) {
         this.ctx = ctx;
         this.busyLock = busyLock;
         this.maxCursors = maxCursors;
@@ -135,6 +140,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
         this.replicatedOnly = replicatedOnly;
         this.autoCloseCursors = autoCloseCursors;
         this.lazy = lazy;
+        this.skipReducerOnUpdate = skipReducerOnUpdate;
         this.protocolVer = protocolVer;
 
         log = ctx.log(getClass());
@@ -263,14 +269,17 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
                     break;
 
                 case SELECT_STATEMENT_TYPE:
-                    qry = new JdbcSqlFieldsQuery(sql, true);
+                    qry = new SqlFieldsQueryEx(sql, true);
 
                     break;
 
                 default:
                     assert req.expectedStatementType() == JdbcStatementType.UPDATE_STMT_TYPE;
 
-                    qry = new JdbcSqlFieldsQuery(sql, false);
+                    qry = new SqlFieldsQueryEx(sql, false);
+
+                    if (skipReducerOnUpdate)
+                        ((SqlFieldsQueryEx)qry).setSkipReducerOnUpdate(true);
             }
 
             qry.setArgs(req.arguments());
@@ -476,7 +485,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
                 if (q.sql() != null)
                     sql = q.sql();
 
-                SqlFieldsQuery qry = new JdbcSqlFieldsQuery(sql, false);
+                SqlFieldsQuery qry = new SqlFieldsQueryEx(sql, false);
 
                 qry.setArgs(q.args());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
index a4af478..88a2e0f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
@@ -37,8 +37,11 @@ public class OdbcConnectionContext implements ClientListenerConnectionContext {
     /** Version 2.1.5: added "lazy" flag. */
     public static final ClientListenerProtocolVersion VER_2_1_5 = ClientListenerProtocolVersion.create(2, 1, 5);
 
+    /** Version 2.3.0: added "skipReducerOnUpdate" flag. */
+    public static final ClientListenerProtocolVersion VER_2_3_0 = ClientListenerProtocolVersion.create(2, 3, 0);
+
     /** Current version. */
-    private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_1_5;
+    private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_3_0;
 
     /** Supported versions. */
     private static final Set<ClientListenerProtocolVersion> SUPPORTED_VERS = new HashSet<>();
@@ -60,6 +63,7 @@ public class OdbcConnectionContext implements ClientListenerConnectionContext {
 
     static {
         SUPPORTED_VERS.add(CURRENT_VER);
+        SUPPORTED_VERS.add(VER_2_1_5);
         SUPPORTED_VERS.add(VER_2_1_0);
     }
 
@@ -98,8 +102,13 @@ public class OdbcConnectionContext implements ClientListenerConnectionContext {
         if (ver.compareTo(VER_2_1_5) >= 0)
             lazy = reader.readBoolean();
 
+        boolean skipReducerOnUpdate = false;
+
+        if (ver.compareTo(VER_2_3_0) >= 0)
+            skipReducerOnUpdate = reader.readBoolean();
+
         handler = new OdbcRequestHandler(ctx, busyLock, maxCursors, distributedJoins,
-                enforceJoinOrder, replicatedOnly, collocated, lazy);
+                enforceJoinOrder, replicatedOnly, collocated, lazy, skipReducerOnUpdate);
 
         parser = new OdbcMessageParser(ctx, ver);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
index 07b41f3..32375fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
@@ -34,6 +34,7 @@ import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 import org.apache.ignite.internal.binary.GridBinaryMarshaller;
+import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.odbc.ClientListenerRequest;
@@ -43,7 +44,6 @@ import org.apache.ignite.internal.processors.odbc.odbc.escape.OdbcEscapeUtils;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.processors.query.GridQueryIndexing;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
-import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -94,6 +94,9 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
     /** Lazy flag. */
     private final boolean lazy;
 
+    /** Update on server flag. */
+    private final boolean skipReducerOnUpdate;
+
     /**
      * Constructor.
      * @param ctx Context.
@@ -104,10 +107,11 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
      * @param replicatedOnly Replicated only flag.
      * @param collocated Collocated flag.
      * @param lazy Lazy flag.
+     * @param skipReducerOnUpdate Skip reducer on update flag.
      */
     public OdbcRequestHandler(GridKernalContext ctx, GridSpinBusyLock busyLock, int maxCursors,
         boolean distributedJoins, boolean enforceJoinOrder, boolean replicatedOnly,
-        boolean collocated, boolean lazy) {
+        boolean collocated, boolean lazy, boolean skipReducerOnUpdate) {
         this.ctx = ctx;
         this.busyLock = busyLock;
         this.maxCursors = maxCursors;
@@ -116,6 +120,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         this.replicatedOnly = replicatedOnly;
         this.collocated = collocated;
         this.lazy = lazy;
+        this.skipReducerOnUpdate = skipReducerOnUpdate;
 
         log = ctx.log(getClass());
     }
@@ -196,8 +201,8 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
      * @param args Arguments.
      * @return Query instance.
      */
-    private SqlFieldsQuery makeQuery(String schema, String sql, Object[] args) {
-        SqlFieldsQuery qry = new SqlFieldsQuery(sql);
+    private SqlFieldsQueryEx makeQuery(String schema, String sql, Object[] args) {
+        SqlFieldsQueryEx qry = new SqlFieldsQueryEx(sql, null);
 
         qry.setArgs(args);
 
@@ -207,6 +212,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         qry.setCollocated(collocated);
         qry.setLazy(lazy);
         qry.setSchema(schema);
+        qry.setSkipReducerOnUpdate(skipReducerOnUpdate);
 
         return qry;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae02a1d3/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index 2703e6d..2f795df 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -310,7 +310,7 @@ org.apache.ignite.internal.jdbc2.JdbcDatabaseMetadata$UpdateMetadataTask
 org.apache.ignite.internal.jdbc2.JdbcQueryTask
 org.apache.ignite.internal.jdbc2.JdbcQueryTask$1
 org.apache.ignite.internal.jdbc2.JdbcQueryTask$QueryResult
-org.apache.ignite.internal.jdbc2.JdbcSqlFieldsQuery
+org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx
 org.apache.ignite.internal.managers.GridManagerAdapter$1$1
 org.apache.ignite.internal.managers.checkpoint.GridCheckpointManager$CheckpointSet
 org.apache.ignite.internal.managers.checkpoint.GridCheckpointRequest
@@ -2094,4 +2094,4 @@ org.apache.ignite.transactions.TransactionRollbackException
 org.apache.ignite.transactions.TransactionState
 org.apache.ignite.transactions.TransactionTimeoutException
 org.apache.ignite.util.AttributeNodeFilter
-org.apache.ignite.internal.processors.cache.persistence.file.AsyncFileIO
\ No newline at end of file
+org.apache.ignite.internal.processors.cache.persistence.file.AsyncFileIO