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 2017/02/08 10:42:41 UTC

[6/7] ignite git commit: Revert "IGNITE-4363: SQL: fixed inner property updates for DML operations."

Revert "IGNITE-4363: SQL: fixed inner property updates for DML operations."

This reverts commit 70cd8e452b94b806a2fe6fe00b4b67ce80eb4373.


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

Branch: refs/heads/ignite-2.0
Commit: bb1ac0a5cfecf4af7e8dcfe86efc75997895c431
Parents: e6cc8cd
Author: devozerov <vo...@gridgain.com>
Authored: Wed Feb 8 13:40:02 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Feb 8 13:40:02 2017 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       |  16 +--
 .../processors/query/GridQueryProcessor.java    |  81 ++++----------
 .../processors/query/GridQueryProperty.java     |  21 ++--
 .../query/h2/DmlStatementsProcessor.java        |  69 ++++++------
 .../query/h2/dml/UpdatePlanBuilder.java         | 105 ++++++-------------
 ...niteCacheAbstractInsertSqlQuerySelfTest.java |   4 -
 .../IgniteCacheAbstractSqlDmlQuerySelfTest.java |   2 +-
 .../IgniteCacheInsertSqlQuerySelfTest.java      |  22 ----
 .../cache/IgniteCacheMergeSqlQuerySelfTest.java |  24 -----
 .../IgniteCacheUpdateSqlQuerySelfTest.java      |  63 ++---------
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 -
 11 files changed, 111 insertions(+), 301 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index f0179ca..0656dda 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -2358,13 +2358,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    // Add parent property before its possible nested properties so that
-                    // resulting parent column comes before columns corresponding to those
-                    // nested properties in the resulting table - that way nested
-                    // properties override will happen properly (first parent, then children).
-                    type.addProperty(prop, key, true);
-
                     processAnnotation(key, sqlAnn, txtAnn, field.getType(), prop, type);
+
+                    type.addProperty(prop, key, true);
                 }
             }
 
@@ -2384,13 +2380,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
 
                     prop.parent(parent);
 
-                    // Add parent property before its possible nested properties so that
-                    // resulting parent column comes before columns corresponding to those
-                    // nested properties in the resulting table - that way nested
-                    // properties override will happen properly (first parent, then children).
-                    type.addProperty(prop, key, true);
-
                     processAnnotation(key, sqlAnn, txtAnn, mtd.getReturnType(), prop, type);
+
+                    type.addProperty(prop, key, true);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 5bfdde8..a239ee2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -64,7 +64,6 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.binary.BinaryObjectEx;
-import org.apache.ignite.internal.binary.BinaryObjectExImpl;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheEntryImpl;
@@ -1949,7 +1948,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     /**
      * Description of type property.
      */
-    private static class ClassProperty implements GridQueryProperty {
+    private static class ClassProperty extends GridQueryProperty {
         /** */
         private final PropertyAccessor accessor;
 
@@ -2042,17 +2041,12 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public String toString() {
             return S.toString(ClassProperty.class, this);
         }
-
-        /** {@inheritDoc} */
-        @Override public GridQueryProperty parent() {
-            return parent;
-        }
     }
 
     /**
      *
      */
-    private class BinaryProperty implements GridQueryProperty {
+    private class BinaryProperty extends GridQueryProperty {
         /** Property name. */
         private String propName;
 
@@ -2136,17 +2130,11 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                 obj = isKeyProp0 == 1 ? key : val;
             }
 
-            if (obj instanceof BinaryObject) {
-                BinaryObject obj0 = (BinaryObject) obj;
-                return fieldValue(obj0);
-            }
-            else if (obj instanceof BinaryObjectBuilder) {
-                BinaryObjectBuilder obj0 = (BinaryObjectBuilder)obj;
+            assert obj instanceof BinaryObject;
 
-                return obj0.getField(name());
-            }
-            else
-                throw new IgniteCheckedException("Unexpected binary object class [type=" + obj.getClass() + ']');
+            BinaryObject obj0 = (BinaryObject)obj;
+
+            return fieldValue(obj0);
         }
 
         /** {@inheritDoc} */
@@ -2156,38 +2144,10 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             if (obj == null)
                 return;
 
-            Object srcObj = obj;
-
-            if (!(srcObj instanceof BinaryObjectBuilder))
-                throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
-
-            if (parent != null)
-                obj = parent.value(key, val);
-
-            boolean needsBuild = false;
-
-            if (obj instanceof BinaryObjectExImpl) {
-                if (parent == null)
-                    throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
-
-                needsBuild = true;
-
-                obj = ((BinaryObjectExImpl)obj).toBuilder();
-            }
-
             if (!(obj instanceof BinaryObjectBuilder))
                 throw new UnsupportedOperationException("Individual properties can be set for binary builders only");
 
             setValue0((BinaryObjectBuilder) obj, propName, propVal, type());
-
-            if (needsBuild) {
-                obj = ((BinaryObjectBuilder) obj).build();
-
-                assert parent != null;
-
-                // And now let's set this newly constructed object to parent
-                setValue0((BinaryObjectBuilder) srcObj, parent.propName, obj, obj.getClass());
-            }
         }
 
         /**
@@ -2264,11 +2224,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
             return isKeyProp0 == 1;
         }
-
-        /** {@inheritDoc} */
-        @Override public GridQueryProperty parent() {
-            return parent;
-        }
     }
 
     /**
@@ -2352,12 +2307,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
         /** {@inheritDoc} */
         @Override public GridQueryProperty property(String name) {
-            GridQueryProperty res = props.get(name);
-
-            if (res == null)
-                res = uppercaseProps.get(name.toUpperCase());
-
-            return res;
+            return getProperty(name);
         }
 
         /** {@inheritDoc} */
@@ -2365,7 +2315,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         @Override public <T> T value(String field, Object key, Object val) throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = property(field);
+            GridQueryProperty prop = getProperty(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2379,7 +2329,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             throws IgniteCheckedException {
             assert field != null;
 
-            GridQueryProperty prop = property(field);
+            GridQueryProperty prop = getProperty(field);
 
             if (prop == null)
                 throw new IgniteCheckedException("Failed to find field '" + field + "' in type '" + name + "'.");
@@ -2519,6 +2469,19 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             fields.put(name, prop.type());
         }
 
+        /**
+         * @param field Property name.
+         * @return Property with given field name.
+         */
+        private GridQueryProperty getProperty(String field) {
+            GridQueryProperty res = props.get(field);
+
+            if (res == null)
+                res = uppercaseProps.get(field.toUpperCase());
+
+            return res;
+        }
+
         /** {@inheritDoc} */
         @Override public boolean valueTextIndex() {
             return valTextIdx;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
index fb4c037..5d74a2e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProperty.java
@@ -22,7 +22,11 @@ import org.apache.ignite.IgniteCheckedException;
 /**
  * Description and access method for query entity field.
  */
-public interface GridQueryProperty {
+public abstract class GridQueryProperty {
+    /** */
+    public GridQueryProperty() {
+    }
+
     /**
      * Gets this property value from the given object.
      *
@@ -31,7 +35,7 @@ public interface GridQueryProperty {
      * @return Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public Object value(Object key, Object val) throws IgniteCheckedException;
+    public abstract Object value(Object key, Object val) throws IgniteCheckedException;
 
     /**
      * Sets this property value for the given object.
@@ -41,26 +45,21 @@ public interface GridQueryProperty {
      * @param propVal Property value.
      * @throws IgniteCheckedException If failed.
      */
-    public void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
+    public abstract void setValue(Object key, Object val, Object propVal) throws IgniteCheckedException;
 
     /**
      * @return Property name.
      */
-    public String name();
+    public abstract String name();
 
     /**
      * @return Class member type.
      */
-    public Class<?> type();
+    public abstract Class<?> type();
 
     /**
      * Property ownership flag.
      * @return {@code true} if this property belongs to key, {@code false} if it belongs to value.
      */
-    public boolean key();
-
-    /**
-     * @return Parent property or {@code null} if this property is not nested.
-     */
-    public GridQueryProperty parent();
+    public abstract boolean key();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
index 7995083..4030758 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/DmlStatementsProcessor.java
@@ -59,6 +59,7 @@ import org.apache.ignite.internal.processors.query.GridQueryProperty;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.h2.dml.FastUpdateArguments;
+import org.apache.ignite.internal.processors.query.h2.dml.KeyValueSupplier;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlanBuilder;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
@@ -480,6 +481,7 @@ public class DmlStatementsProcessor {
         while (it.hasNext()) {
             List<?> e = it.next();
             Object key = e.get(0);
+            Object val = (hasNewVal ? e.get(valColIdx) : e.get(1));
 
             Object newVal;
 
@@ -498,6 +500,9 @@ public class DmlStatementsProcessor {
             if (newVal == null)
                 throw new IgniteSQLException("New value for UPDATE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
+            if (bin && !(val instanceof BinaryObject))
+                val = cctx.grid().binary().toBinary(val);
+
             // Skip key and value - that's why we start off with 2nd column
             for (int i = 0; i < plan.tbl.getColumns().length - 2; i++) {
                 Column c = plan.tbl.getColumn(i + 2);
@@ -509,10 +514,13 @@ public class DmlStatementsProcessor {
 
                 boolean hasNewColVal = newColVals.containsKey(c.getName());
 
-                if (!hasNewColVal)
+                // Binary objects get old field values from the Builder, so we can skip what we're not updating
+                if (bin && !hasNewColVal)
                     continue;
 
-                Object colVal = newColVals.get(c.getName());
+                // Column values that have been explicitly specified have priority over field values in old or new _val
+                // If no value given for the column, then we expect to find it in value, and not in key - hence null arg.
+                Object colVal = hasNewColVal ? newColVals.get(c.getName()) : prop.value(null, val);
 
                 // UPDATE currently does not allow to modify key or its fields, so we must be safe to pass null as key.
                 desc.setColumnValue(null, newVal, colVal, i);
@@ -688,8 +696,8 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(),
-                plan);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
+                plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
 
             cctx.cache().put(t.getKey(), t.getValue());
             return 1;
@@ -701,7 +709,8 @@ public class DmlStatementsProcessor {
             for (Iterator<List<?>> it = cursor.iterator(); it.hasNext();) {
                 List<?> row = it.next();
 
-                IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
+                IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier, plan.valSupplier,
+                    plan.keyColIdx, plan.valColIdx, desc);
 
                 rows.put(t.getKey(), t.getValue());
 
@@ -733,7 +742,8 @@ public class DmlStatementsProcessor {
 
         // If we have just one item to put, just do so
         if (plan.rowsNum == 1) {
-            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next(), plan);
+            IgniteBiTuple t = rowToKeyValue(cctx, cursor.iterator().next().toArray(), plan.colNames, plan.colTypes,
+                plan.keySupplier, plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
 
             if (cctx.cache().putIfAbsent(t.getKey(), t.getValue()))
                 return 1;
@@ -758,7 +768,8 @@ public class DmlStatementsProcessor {
             while (it.hasNext()) {
                 List<?> row = it.next();
 
-                final IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
+                final IgniteBiTuple t = rowToKeyValue(cctx, row.toArray(), plan.colNames, plan.colTypes, plan.keySupplier,
+                    plan.valSupplier, plan.keyColIdx, plan.valColIdx, desc);
 
                 rows.put(t.getKey(), new InsertEntryProcessor(t.getValue()));
 
@@ -826,14 +837,21 @@ public class DmlStatementsProcessor {
      * Convert row presented as an array of Objects into key-value pair to be inserted to cache.
      * @param cctx Cache context.
      * @param row Row to process.
-     * @param plan Update plan.
+     * @param cols Query cols.
+     * @param colTypes Column types to convert data from {@code row} to.
+     * @param keySupplier Key instantiation method.
+     * @param valSupplier Key instantiation method.
+     * @param keyColIdx Key column index, or {@code -1} if no key column is mentioned in {@code cols}.
+     * @param valColIdx Value column index, or {@code -1} if no value column is mentioned in {@code cols}.
+     * @param rowDesc Row descriptor.
      * @throws IgniteCheckedException if failed.
      */
     @SuppressWarnings({"unchecked", "ConstantConditions", "ResultOfMethodCallIgnored"})
-    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, List<?> row, UpdatePlan plan)
-        throws IgniteCheckedException {
-        Object key = plan.keySupplier.apply(row);
-        Object val = plan.valSupplier.apply(row);
+    private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, Object[] row, String[] cols,
+        int[] colTypes, KeyValueSupplier keySupplier, KeyValueSupplier valSupplier, int keyColIdx, int valColIdx,
+        GridH2RowDescriptor rowDesc) throws IgniteCheckedException {
+        Object key = keySupplier.apply(F.asList(row));
+        Object val = valSupplier.apply(F.asList(row));
 
         if (key == null)
             throw new IgniteSQLException("Key for INSERT or MERGE must not be null",  IgniteQueryErrorCode.NULL_KEY);
@@ -841,32 +859,13 @@ public class DmlStatementsProcessor {
         if (val == null)
             throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
 
-        GridQueryTypeDescriptor desc = plan.tbl.rowDescriptor().type();
-
-        Map<String, Object> newColVals = new HashMap<>();
-
-        for (int i = 0; i < plan.colNames.length; i++) {
-            if (i == plan.keyColIdx || i == plan.valColIdx)
-                continue;
-
-            newColVals.put(plan.colNames[i], convert(row.get(i), plan.colNames[i],
-                plan.tbl.rowDescriptor(), plan.colTypes[i]));
-        }
-
-        // We update columns in the order specified by the table for a reason - table's
-        // column order preserves their precedence for correct update of nested properties.
-        Column[] cols = plan.tbl.getColumns();
+        GridQueryTypeDescriptor desc = rowDesc.type();
 
-        // First 2 columns are _key and _val, skip 'em.
-        for (int i = 2; i < cols.length; i++) {
-            String colName = cols[i].getName();
-
-            if (!newColVals.containsKey(colName))
+        for (int i = 0; i < cols.length; i++) {
+            if (i == keyColIdx || i == valColIdx)
                 continue;
 
-            Object colVal = newColVals.get(colName);
-
-            desc.setValue(colName, key, val, colVal);
+            desc.setValue(cols[i], key, val, convert(row[i], cols[i], rowDesc, colTypes[i]));
         }
 
         if (cctx.binaryMarshaller()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
----------------------------------------------------------------------
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 ce2971a..fdcd164 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
@@ -48,7 +48,6 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate;
 import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.h2.command.Prepared;
 import org.h2.table.Column;
@@ -193,8 +192,8 @@ public final class UpdatePlanBuilder {
                 hasValProps = true;
         }
 
-        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true, false);
-        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false, false);
+        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true);
+        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false);
 
         if (stmt instanceof GridSqlMerge)
             return UpdatePlan.forMerge(tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx,
@@ -254,6 +253,8 @@ public final class UpdatePlanBuilder {
             GridSqlSelect sel;
 
             if (stmt instanceof GridSqlUpdate) {
+                boolean bin = desc.context().binaryMarshaller();
+
                 List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
 
                 int valColIdx = -1;
@@ -281,10 +282,20 @@ public final class UpdatePlanBuilder {
                 if (hasNewVal)
                     valColIdx += 2;
 
-                int newValColIdx = (hasNewVal ? valColIdx : 1);
+                int newValColIdx;
+
+                if (!hasProps) // No distinct properties, only whole new value - let's take it
+                    newValColIdx = valColIdx;
+                else if (bin) // We update distinct columns in binary mode - let's choose correct index for the builder
+                    newValColIdx = (hasNewVal ? valColIdx : 1);
+                else // Distinct properties, non binary mode - let's instantiate.
+                    newValColIdx = -1;
 
-                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps,
-                    false, true);
+                // We want supplier to take present value only in case of binary mode as it will create
+                // whole new object as a result anyway, so we don't need to copy previous property values explicitly.
+                // Otherwise we always want it to instantiate new object whose properties we will later
+                // set to current values.
+                KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false);
 
                 sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
 
@@ -308,11 +319,11 @@ public final class UpdatePlanBuilder {
      * @param hasProps Whether column list affects individual properties of key or value.
      * @param key Whether supplier should be created for key or for value.
      * @return Closure returning key or value.
-     * @throws IgniteCheckedException If failed.
+     * @throws IgniteCheckedException
      */
     @SuppressWarnings({"ConstantConditions", "unchecked"})
     private static KeyValueSupplier createSupplier(final GridCacheContext<?, ?> cctx, GridQueryTypeDescriptor desc,
-        final int colIdx, boolean hasProps, final boolean key, boolean forUpdate) throws IgniteCheckedException {
+                                                   final int colIdx, boolean hasProps, final boolean key) throws IgniteCheckedException {
         final String typeName = key ? desc.keyTypeName() : desc.valueTypeName();
 
         //Try to find class for the key locally.
@@ -321,10 +332,15 @@ public final class UpdatePlanBuilder {
 
         boolean isSqlType = GridQueryProcessor.isSqlType(cls);
 
-        // If we don't need to construct anything from scratch, just return value from given list.
-        if (isSqlType || !hasProps) {
+        // If we don't need to construct anything from scratch, just return value from array.
+        if (isSqlType || !hasProps || !cctx.binaryMarshaller()) {
             if (colIdx != -1)
-                return new PlainValueSupplier(colIdx);
+                return new KeyValueSupplier() {
+                    /** {@inheritDoc} */
+                    @Override public Object apply(List<?> arg) throws IgniteCheckedException {
+                        return arg.get(colIdx);
+                    }
+                };
             else if (isSqlType)
                 // Non constructable keys and values (SQL types) must be present in the query explicitly.
                 throw new IgniteCheckedException((key ? "Key" : "Value") + " is missing from query");
@@ -336,12 +352,7 @@ public final class UpdatePlanBuilder {
                 return new KeyValueSupplier() {
                     /** {@inheritDoc} */
                     @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                        Object obj = arg.get(colIdx);
-
-                        if (obj == null)
-                            return null;
-
-                        BinaryObject bin = cctx.grid().binary().toBinary(obj);
+                        BinaryObject bin = cctx.grid().binary().toBinary(arg.get(colIdx));
 
                         return cctx.grid().binary().builder(bin);
                     }
@@ -358,26 +369,6 @@ public final class UpdatePlanBuilder {
             }
         }
         else {
-            if (colIdx != -1) {
-                if (forUpdate && colIdx == 1) {
-                    // It's the case when the old value has to be taken as the basis for the new one on UPDATE,
-                    // so we have to clone it. And on UPDATE we don't expect any key supplier.
-                    assert !key;
-
-                    return new KeyValueSupplier() {
-                        /** {@inheritDoc} */
-                        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-                            byte[] oldPropBytes = cctx.marshaller().marshal(arg.get(1));
-
-                            // colVal is another object now, we can mutate it
-                            return cctx.marshaller().unmarshal(oldPropBytes, U.resolveClassLoader(cctx.gridConfig()));
-                        }
-                    };
-                }
-                else // We either are not updating, or the new value is given explicitly, no cloning needed.
-                    return new PlainValueSupplier(colIdx);
-            }
-
             Constructor<?> ctor;
 
             try {
@@ -399,12 +390,8 @@ public final class UpdatePlanBuilder {
                             return ctor0.newInstance();
                         }
                         catch (Exception e) {
-                            if (S.INCLUDE_SENSITIVE)
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
-                            else
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + '.', e);
+                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
+                                (key ? "key" : "value"), e);
                         }
                     }
                 };
@@ -418,12 +405,8 @@ public final class UpdatePlanBuilder {
                             return GridUnsafe.allocateInstance(cls);
                         }
                         catch (InstantiationException e) {
-                            if (S.INCLUDE_SENSITIVE)
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + " [type=" + typeName + ']', e);
-                            else
-                                throw new IgniteCheckedException("Failed to instantiate " +
-                                    (key ? "key" : "value") + '.', e);
+                            throw new IgniteCheckedException("Failed to invoke default ctor for " +
+                                (key ? "key" : "value"), e);
                         }
                     }
                 };
@@ -431,6 +414,8 @@ public final class UpdatePlanBuilder {
         }
     }
 
+
+
     /**
      * @param target Expression to extract the table from.
      * @return Back end table for this element.
@@ -498,26 +483,4 @@ public final class UpdatePlanBuilder {
 
         return false;
     }
-
-    /**
-     * Simple supplier that just takes specified element of a given row.
-     */
-    private final static class PlainValueSupplier implements KeyValueSupplier {
-        /** Index of column to use. */
-        private final int colIdx;
-
-        /**
-         * Constructor.
-         *
-         * @param colIdx Column index.
-         */
-        private PlainValueSupplier(int colIdx) {
-            this.colIdx = colIdx;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object apply(List<?> arg) throws IgniteCheckedException {
-            return arg.get(colIdx);
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
index 626846b..86d01c7 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
@@ -46,8 +46,6 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.junits.IgniteTestResources;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
-import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
-
 /**
  *
  */
@@ -128,8 +126,6 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends GridComm
             createCaches();
         else
             createBinaryCaches();
-
-        ignite(0).createCache(cacheConfig("I2AT", true, false, Integer.class, AllTypes.class));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
index 3c92fdf..649012f 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractSqlDmlQuerySelfTest.java
@@ -65,7 +65,7 @@ public abstract class IgniteCacheAbstractSqlDmlQuerySelfTest extends GridCommonA
     /**
      * @return whether {@link #marsh} is an instance of {@link BinaryMarshaller} or not.
      */
-    protected boolean isBinaryMarshaller() {
+    private boolean isBinaryMarshaller() {
         return marsh instanceof BinaryMarshaller;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
index f91f405..e9c21dc 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInsertSqlQuerySelfTest.java
@@ -17,8 +17,6 @@
 
 package org.apache.ignite.internal.processors.cache;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.concurrent.Callable;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCache;
@@ -204,24 +202,4 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
-
-    /**
-     *
-     */
-    public void testNestedFieldsHandling() {
-        IgniteCache<Integer, IgniteCacheUpdateSqlQuerySelfTest.AllTypes> p = ignite(0).cache("I2AT");
-
-        p.query(new SqlFieldsQuery("insert into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
-            "values (1, ?, ?, ?, 'sss')") .setArgs(new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L),
-            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new IgniteCacheUpdateSqlQuerySelfTest.AllTypes(1L)));
-
-        IgniteCacheUpdateSqlQuerySelfTest.AllTypes res = p.get(1);
-
-        IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType resInner = new IgniteCacheUpdateSqlQuerySelfTest.AllTypes.InnerType(50L);
-
-        resInner.innerStrCol = "sss";
-        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
-
-        assertEquals(resInner, res.innerTypeCol);
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
index d9a2d9e..32b7a12 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheMergeSqlQuerySelfTest.java
@@ -17,13 +17,9 @@
 
 package org.apache.ignite.internal.processors.cache;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 
-import static org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest.AllTypes;
-
 /**
  *
  */
@@ -153,24 +149,4 @@ public class IgniteCacheMergeSqlQuerySelfTest extends IgniteCacheAbstractInsertS
 
         assertEquals(createPerson(2, "Alex"), p.get(new Key4(2)));
     }
-
-    /**
-     *
-     */
-    public void testNestedFieldsHandling() {
-        IgniteCache<Integer, AllTypes> p = ignite(0).cache("I2AT");
-
-        p.query(new SqlFieldsQuery("merge into AllTypes(_key, innerTypeCol, arrListCol, _val, innerStrCol) " +
-            "values (1, ?, ?, ?, 'sss')") .setArgs(new AllTypes.InnerType(50L),
-            new ArrayList<>(Arrays.asList(3L, 2L, 1L)), new AllTypes(1L)));
-
-        AllTypes res = p.get(1);
-
-        AllTypes.InnerType resInner = new AllTypes.InnerType(50L);
-
-        resInner.innerStrCol = "sss";
-        resInner.arrListCol = new ArrayList<>(Arrays.asList(3L, 2L, 1L));
-
-        assertEquals(resInner, res.innerTypeCol);
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
index c3d9d8e..575f617 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheUpdateSqlQuerySelfTest.java
@@ -44,12 +44,6 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         ignite(0).createCache(createAllTypesCacheConfig());
     }
 
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-        ignite(0).cache("L2AT").clear();
-    }
-
     /**
      *
      */
@@ -188,19 +182,17 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\"," +
             "\"tsCol\") values(2, ?, '2016-11-30 12:00:00', false, DATE '2016-12-01')").setArgs(new AllTypes(2L)));
 
-        // Look ma, no hands: first we set value of inner object column (innerTypeCol), then update only one of its
-        // fields (innerLongCol), while leaving another inner property (innerStrCol) as specified by innerTypeCol.
-        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = ?, \"doubleCol\" = CAST('50' as INT)," +
+        cache.query(new SqlFieldsQuery("select \"primitiveIntsCol\" from \"AllTypes\"")).getAll();
+
+        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"doubleCol\" = CAST('50' as INT)," +
             " \"booleanCol\" = 80, \"innerTypeCol\" = ?, \"strCol\" = PI(), \"shortCol\" = " +
             "CAST(WEEK(PARSEDATETIME('2016-11-30', 'yyyy-MM-dd')) as VARCHAR), " +
             "\"sqlDateCol\"=TIMESTAMP '2016-12-02 13:47:00', \"tsCol\"=TIMESTAMPADD('MI', 2, " +
             "DATEADD('DAY', 2, \"tsCol\")), \"primitiveIntsCol\" = ?, \"bytesCol\" = ?")
-            .setArgs(5, new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
+            .setArgs(new AllTypes.InnerType(80L), new int[] {2, 3}, new Byte[] {4, 5, 6}));
 
         AllTypes res = (AllTypes) cache.get(2L);
 
-        assertNotNull(res);
-
         assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
         assertEquals(50.0, res.doubleCol);
         assertEquals(2L, (long) res.longCol);
@@ -210,11 +202,7 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertTrue(Arrays.equals(new Byte[] {4, 5, 6}, res.bytesCol));
         assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
         assertTrue(Arrays.equals(new int[] {2, 3}, res.primitiveIntsCol));
-
-        AllTypes.InnerType expInnerType = new AllTypes.InnerType(80L);
-        expInnerType.innerLongCol = 5L;
-
-        assertEquals(expInnerType, res.innerTypeCol);
+        assertEquals(new AllTypes.InnerType(80L), res.innerTypeCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
         assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-12-03 00:02:00"), res.tsCol);
         assertEquals(2, res.intCol);
@@ -225,45 +213,6 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         assertEquals(49, res.shortCol);
     }
 
-    /** */
-    public void testSingleInnerFieldUpdate() throws ParseException {
-        IgniteCache cache = ignite(0).cache("L2AT");
-
-        cache.query(new SqlFieldsQuery("insert into \"AllTypes\"(_key, _val, \"dateCol\", \"booleanCol\") values(2, ?," +
-            "'2016-11-30 12:00:00', false)").setArgs(new AllTypes(2L)));
-
-        assertFalse(cache.query(new SqlFieldsQuery("select * from \"AllTypes\"")).getAll().isEmpty());
-
-        cache.query(new SqlFieldsQuery("update \"AllTypes\" set \"innerLongCol\" = 5"));
-
-        AllTypes res = (AllTypes) cache.get(2L);
-
-        assertNotNull(res);
-
-        assertEquals(new BigDecimal(301.0).doubleValue(), res.bigDecimalCol.doubleValue());
-        assertEquals(3.01, res.doubleCol);
-        assertEquals(2L, (long) res.longCol);
-        assertFalse(res.booleanCol);
-
-        assertEquals("2", res.strCol);
-        assertTrue(Arrays.equals(new byte[] {0, 1}, res.primitiveBytesCol));
-        assertTrue(Arrays.deepEquals(new Byte[] {0, 1}, res.bytesCol));
-        assertTrue(Arrays.deepEquals(new Integer[] {0, 1}, res.intsCol));
-        assertTrue(Arrays.equals(new int[] {0, 1}, res.primitiveIntsCol));
-
-        AllTypes.InnerType expInnerType = new AllTypes.InnerType(2L);
-        expInnerType.innerLongCol = 5L;
-
-        assertEquals(expInnerType, res.innerTypeCol);
-        assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:SS").parse("2016-11-30 12:00:00"), res.dateCol);
-        assertNull(res.tsCol);
-        assertEquals(2, res.intCol);
-        assertEquals(AllTypes.EnumType.ENUMTRUE, res.enumCol);
-        assertNull(res.sqlDateCol);
-
-        assertEquals(-23000, res.shortCol);
-    }
-
     /**
      *
      */
@@ -359,7 +308,7 @@ public class IgniteCacheUpdateSqlQuerySelfTest extends IgniteCacheAbstractSqlDml
         InnerType innerTypeCol;
 
         /** */
-        static class InnerType implements Serializable {
+        static final class InnerType implements Serializable {
             /** */
             @QuerySqlField
             Long innerLongCol;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb1ac0a5/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index 69285f1..e412828 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -578,11 +578,6 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
                 @Override public boolean key() {
                     return false;
                 }
-
-                /** */
-                @Override public GridQueryProperty parent() {
-                    return null;
-                }
             };
         }