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 2016/12/06 08:40:22 UTC

[25/50] ignite git commit: IGNITE-4320: Minor fixes inside DML engine. This closes #1292.

IGNITE-4320: Minor fixes inside DML engine. This closes #1292.


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

Branch: refs/heads/ignite-comm-balance-master
Commit: b0127d3c57601c475d186dd3becbc17829a657ce
Parents: 0b7c62d
Author: Alexander Paschenko <al...@gmail.com>
Authored: Mon Nov 28 13:24:41 2016 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Nov 28 13:24:41 2016 +0300

----------------------------------------------------------------------
 .../query/h2/DmlStatementsProcessor.java        | 143 +++++++++----------
 .../query/h2/dml/UpdatePlanBuilder.java         |  16 +--
 2 files changed, 74 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b0127d3c/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 469e36c..d57f95f 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
@@ -53,6 +53,7 @@ import org.apache.ignite.internal.processors.query.GridQueryCancel;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.processors.query.GridQueryFieldsResult;
 import org.apache.ignite.internal.processors.query.GridQueryFieldsResultAdapter;
+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;
@@ -464,22 +465,6 @@ public class DmlStatementsProcessor {
 
         long res = 0;
 
-        CacheOperationContext opCtx = cctx.operationContextPerCall();
-
-        // Force keepBinary for operation context to avoid binary deserialization inside entry processor
-        if (cctx.binaryMarshaller()) {
-            CacheOperationContext newOpCtx = null;
-
-            if (opCtx == null)
-                // Mimics behavior of GridCacheAdapter#keepBinary and GridCacheProxyImpl#keepBinary
-                newOpCtx = new CacheOperationContext(false, null, true, null, false, null);
-            else if (!opCtx.isKeepBinary())
-                newOpCtx = opCtx.keepBinary();
-
-            if (newOpCtx != null)
-                cctx.operationContextPerCall(newOpCtx);
-        }
-
         Map<Object, EntryProcessor<Object, Object, Boolean>> rows = new LinkedHashMap<>();
 
         // Keys that failed to UPDATE due to concurrent updates.
@@ -487,97 +472,101 @@ public class DmlStatementsProcessor {
 
         SQLException resEx = null;
 
-        try {
-            Iterator<List<?>> it = cursor.iterator();
+        Iterator<List<?>> it = cursor.iterator();
 
-            while (it.hasNext()) {
-                List<?> e = it.next();
-                Object key = e.get(0);
-                Object val = (hasNewVal ? e.get(valColIdx) : e.get(1));
+        while (it.hasNext()) {
+            List<?> e = it.next();
+            Object key = e.get(0);
+            Object val = (hasNewVal ? e.get(valColIdx) : e.get(1));
 
-                Object newVal;
+            Object newVal;
 
-                Map<String, Object> newColVals = new HashMap<>();
+            Map<String, Object> newColVals = new HashMap<>();
 
-                for (int i = 0; i < plan.colNames.length; i++) {
-                    if (hasNewVal && i == valColIdx - 2)
-                        continue;
+            for (int i = 0; i < plan.colNames.length; i++) {
+                if (hasNewVal && i == valColIdx - 2)
+                    continue;
 
-                    newColVals.put(plan.colNames[i], e.get(i + 2));
-                }
+                newColVals.put(plan.colNames[i], e.get(i + 2));
+            }
 
-                newVal = plan.valSupplier.apply(e);
+            newVal = plan.valSupplier.apply(e);
 
-                if (bin && !(val instanceof BinaryObject))
-                    val = cctx.grid().binary().toBinary(val);
+            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);
+            // 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);
 
-                    boolean hasNewColVal = newColVals.containsKey(c.getName());
+                GridQueryProperty prop = desc.type().property(c.getName());
 
-                    // Binary objects get old field values from the Builder, so we can skip what we're not updating
-                    if (bin && !hasNewColVal)
-                        continue;
+                if (prop.key())
+                    continue; // Don't get values of key's columns - we won't use them anyway
 
-                    Object colVal = hasNewColVal ? newColVals.get(c.getName()) : desc.columnValue(key, val, i);
+                boolean hasNewColVal = newColVals.containsKey(c.getName());
 
-                    desc.setColumnValue(key, newVal, colVal, i);
-                }
+                // Binary objects get old field values from the Builder, so we can skip what we're not updating
+                if (bin && !hasNewColVal)
+                    continue;
 
-                if (bin && hasProps) {
-                    assert newVal instanceof BinaryObjectBuilder;
+                // 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);
 
-                    newVal = ((BinaryObjectBuilder) newVal).build();
-                }
+                // 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);
+            }
 
-                Object srcVal = e.get(1);
+            if (bin && hasProps) {
+                assert newVal instanceof BinaryObjectBuilder;
 
-                if (bin && !(srcVal instanceof BinaryObject))
-                    srcVal = cctx.grid().binary().toBinary(srcVal);
+                newVal = ((BinaryObjectBuilder) newVal).build();
+            }
 
-                rows.put(key, new ModifyingEntryProcessor(srcVal, new EntryValueUpdater(newVal)));
+            Object srcVal = e.get(1);
 
-                if ((pageSize > 0 && rows.size() == pageSize) || (!it.hasNext())) {
-                    PageProcessingResult pageRes = processPage(cctx, rows);
+            if (bin && !(srcVal instanceof BinaryObject))
+                srcVal = cctx.grid().binary().toBinary(srcVal);
 
-                    res += pageRes.cnt;
+            rows.put(key, new ModifyingEntryProcessor(srcVal, new EntryValueUpdater(newVal)));
 
-                    failedKeys.addAll(F.asList(pageRes.errKeys));
+            if ((pageSize > 0 && rows.size() == pageSize) || (!it.hasNext())) {
+                PageProcessingResult pageRes = processPage(cctx, rows);
 
-                    if (pageRes.ex != null) {
-                        if (resEx == null)
-                            resEx = pageRes.ex;
-                        else
-                            resEx.setNextException(pageRes.ex);
-                    }
+                res += pageRes.cnt;
 
-                    if (it.hasNext())
-                        rows.clear(); // No need to clear after the last batch.
+                failedKeys.addAll(F.asList(pageRes.errKeys));
+
+                if (pageRes.ex != null) {
+                    if (resEx == null)
+                        resEx = pageRes.ex;
+                    else
+                        resEx.setNextException(pageRes.ex);
                 }
-            }
 
-            if (resEx != null) {
-                if (!F.isEmpty(failedKeys)) {
-                    // Don't go for a re-run if processing of some keys yielded exceptions and report keys that
-                    // had been modified concurrently right away.
-                    String msg = "Failed to UPDATE some keys because they had been modified concurrently " +
-                        "[keys=" + failedKeys + ']';
+                if (it.hasNext())
+                    rows.clear(); // No need to clear after the last batch.
+            }
+        }
 
-                    SQLException dupEx = createJdbcSqlException(msg, IgniteQueryErrorCode.CONCURRENT_UPDATE);
+        if (resEx != null) {
+            if (!F.isEmpty(failedKeys)) {
+                // Don't go for a re-run if processing of some keys yielded exceptions and report keys that
+                // had been modified concurrently right away.
+                String msg = "Failed to UPDATE some keys because they had been modified concurrently " +
+                    "[keys=" + failedKeys + ']';
 
-                    dupEx.setNextException(resEx);
+                SQLException dupEx = createJdbcSqlException(msg, IgniteQueryErrorCode.CONCURRENT_UPDATE);
 
-                    resEx = dupEx;
-                }
+                dupEx.setNextException(resEx);
 
-                throw new IgniteSQLException(resEx);
+                resEx = dupEx;
             }
+
+            throw new IgniteSQLException(resEx);
         }
-        finally {
-            cctx.operationContextPerCall(opCtx);
-        }
+
 
         return new UpdateResult(res, failedKeys.toArray());
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b0127d3c/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 15c94c3..549b901 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
@@ -99,7 +99,7 @@ public final class UpdatePlanBuilder {
 
         GridSqlColumn[] cols;
 
-        boolean isTableSubqry;
+        boolean isTwoStepSubqry;
 
         int rowsNum;
 
@@ -116,8 +116,8 @@ public final class UpdatePlanBuilder {
 
             cols = ins.columns();
             sel = DmlAstUtils.selectForInsertOrMerge(cols, ins.rows(), ins.query(), desc);
-            isTableSubqry = (ins.query() != null);
-            rowsNum = isTableSubqry ? 0 : ins.rows().size();
+            isTwoStepSubqry = (ins.query() != null);
+            rowsNum = isTwoStepSubqry ? 0 : ins.rows().size();
         }
         else if (stmt instanceof GridSqlMerge) {
             GridSqlMerge merge = (GridSqlMerge) stmt;
@@ -137,14 +137,14 @@ public final class UpdatePlanBuilder {
 
             cols = merge.columns();
             sel = DmlAstUtils.selectForInsertOrMerge(cols, merge.rows(), merge.query(), desc);
-            isTableSubqry = (merge.query() != null);
-            rowsNum = isTableSubqry ? 0 : merge.rows().size();
+            isTwoStepSubqry = (merge.query() != null);
+            rowsNum = isTwoStepSubqry ? 0 : merge.rows().size();
         }
         else throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']',
                 IgniteQueryErrorCode.UNEXPECTED_OPERATION);
 
         // Let's set the flag only for subqueries that have their FROM specified.
-        isTableSubqry = (isTableSubqry && (sel instanceof GridSqlUnion ||
+        isTwoStepSubqry = (isTwoStepSubqry && (sel instanceof GridSqlUnion ||
             (sel instanceof GridSqlSelect && ((GridSqlSelect) sel).from() != null)));
 
         int keyColIdx = -1;
@@ -189,10 +189,10 @@ public final class UpdatePlanBuilder {
 
         if (stmt instanceof GridSqlMerge)
             return UpdatePlan.forMerge(tbl.dataTable(), colNames, keySupplier, valSupplier, keyColIdx, valColIdx,
-                sel.getSQL(), !isTableSubqry, rowsNum);
+                sel.getSQL(), !isTwoStepSubqry, rowsNum);
         else
             return UpdatePlan.forInsert(tbl.dataTable(), colNames, keySupplier, valSupplier, keyColIdx, valColIdx,
-                sel.getSQL(), !isTableSubqry, rowsNum);
+                sel.getSQL(), !isTwoStepSubqry, rowsNum);
     }
 
     /**