IGNITE-4409: Fixed UUID deserialization issue during DML command execution. This closes #1554.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/32c3d6bd Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/32c3d6bd Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/32c3d6bd Branch: refs/heads/master Commit: 32c3d6bd66030b70ede6d1dfa58fd81eee7829ba Parents: 0130b09 Author: Alexander Paschenko <[email protected]> Authored: Mon Feb 20 18:04:20 2017 +0300 Committer: devozerov <[email protected]> Committed: Mon Feb 20 18:04:20 2017 +0300 ---------------------------------------------------------------------- .../query/h2/DmlStatementsProcessor.java | 48 ++++++++++++++------ ...niteCacheAbstractInsertSqlQuerySelfTest.java | 6 ++- .../IgniteCacheInsertSqlQuerySelfTest.java | 14 ++++++ 3 files changed, 54 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/32c3d6bd/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 78c5bbc..60bc483 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 @@ -55,6 +55,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.GridQueryProcessor; import org.apache.ignite.internal.processors.query.GridQueryProperty; import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.IgniteSQLException; @@ -577,8 +578,11 @@ public class DmlStatementsProcessor { if (hasNewVal && i == valColIdx - 2) continue; - newColVals.put(plan.colNames[i], convert(e.get(i + 2), plan.colNames[i], - plan.tbl.rowDescriptor(), plan.colTypes[i])); + GridQueryProperty prop = plan.tbl.rowDescriptor().type().property(plan.colNames[i]); + + assert prop != null; + + newColVals.put(plan.colNames[i], convert(e.get(i + 2), desc, prop.type(), plan.colTypes[i])); } newVal = plan.valSupplier.apply(e); @@ -668,24 +672,18 @@ public class DmlStatementsProcessor { * Convert value to column's expected type by means of H2. * * @param val Source value. - * @param colName Column name to search for property. * @param desc Row descriptor. + * @param expCls Expected value class. * @param type Expected column type to convert to. * @return Converted object. * @throws IgniteCheckedException if failed. */ @SuppressWarnings({"ConstantConditions", "SuspiciousSystemArraycopy"}) - private static Object convert(Object val, String colName, GridH2RowDescriptor desc, int type) + private static Object convert(Object val, GridH2RowDescriptor desc, Class<?> expCls, int type) throws IgniteCheckedException { if (val == null) return null; - GridQueryProperty prop = desc.type().property(colName); - - assert prop != null; - - Class<?> expCls = prop.type(); - Class<?> currCls = val.getClass(); if (val instanceof Date && currCls != Date.class && expCls == Date.class) { @@ -694,6 +692,11 @@ public class DmlStatementsProcessor { return new Date(((Date) val).getTime()); } + // User-given UUID is always serialized by H2 to byte array, so we have to deserialize manually + if (type == Value.UUID && currCls == byte[].class) + return U.unmarshal(desc.context().marshaller(), (byte[]) val, + U.resolveClassLoader(desc.context().gridConfig())); + // We have to convert arrays of reference types manually - see https://issues.apache.org/jira/browse/IGNITE-4327 // Still, we only can convert from Object[] to something more precise. if (type == Value.ARRAY && currCls != expCls) { @@ -935,22 +938,41 @@ public class DmlStatementsProcessor { private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, Object[] row, String[] cols, int[] colTypes, KeyValueSupplier keySupplier, KeyValueSupplier valSupplier, int keyColIdx, int valColIdx, GridH2RowDescriptor rowDesc) throws IgniteCheckedException { + GridQueryTypeDescriptor desc = rowDesc.type(); + Object key = keySupplier.apply(F.asList(row)); + + if (GridQueryProcessor.isSqlType(desc.keyClass())) { + assert keyColIdx != -1; + + key = convert(key, rowDesc, desc.keyClass(), colTypes[keyColIdx]); + } + Object val = valSupplier.apply(F.asList(row)); + if (GridQueryProcessor.isSqlType(desc.valueClass())) { + assert valColIdx != -1; + + val = convert(val, rowDesc, desc.valueClass(), colTypes[valColIdx]); + } + if (key == null) throw new IgniteSQLException("Key for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_KEY); if (val == null) throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE); - GridQueryTypeDescriptor desc = rowDesc.type(); - for (int i = 0; i < cols.length; i++) { if (i == keyColIdx || i == valColIdx) continue; - desc.setValue(cols[i], key, val, convert(row[i], cols[i], rowDesc, colTypes[i])); + GridQueryProperty prop = desc.property(cols[i]); + + assert prop != null; + + Class<?> expCls = prop.type(); + + desc.setValue(cols[i], key, val, convert(row[i], rowDesc, expCls, colTypes[i])); } if (cctx.binaryMarshaller()) { http://git-wip-us.apache.org/repos/asf/ignite/blob/32c3d6bd/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 86d01c7..4470a48 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 @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.UUID; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryAbstractIdentityResolver; import org.apache.ignite.binary.BinaryArrayIdentityResolver; @@ -131,18 +132,21 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends GridComm /** * */ - protected void createCaches() { + void createCaches() { ignite(0).createCache(cacheConfig("S2P", true, false, String.class, Person.class, String.class, String.class)); ignite(0).createCache(cacheConfig("I2P", true, false, Integer.class, Person.class)); ignite(0).createCache(cacheConfig("K2P", true, false, Key.class, Person.class)); ignite(0).createCache(cacheConfig("K22P", true, true, Key2.class, Person2.class)); ignite(0).createCache(cacheConfig("I2I", true, false, Integer.class, Integer.class)); + ignite(0).createCache(cacheConfig("U2I", true, false, UUID.class, Integer.class)); } /** * */ final void createBinaryCaches() { + ignite(0).createCache(cacheConfig("U2I", true, false, UUID.class, Integer.class)); + { CacheConfiguration s2pCcfg = cacheConfig("S2P", true, false); http://git-wip-us.apache.org/repos/asf/ignite/blob/32c3d6bd/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 e9c21dc..471b791 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,6 +17,7 @@ package org.apache.ignite.internal.processors.cache; +import java.util.UUID; import java.util.concurrent.Callable; import javax.cache.CacheException; import org.apache.ignite.IgniteCache; @@ -202,4 +203,17 @@ public class IgniteCacheInsertSqlQuerySelfTest extends IgniteCacheAbstractInsert assertEquals(createPerson(2, "Alex"), p.get(new Key4(2))); } + + /** + * + */ + public void testUuidHandling() { + IgniteCache<UUID, Integer> p = ignite(0).cache("U2I"); + + UUID id = UUID.randomUUID(); + + p.query(new SqlFieldsQuery("insert into Integer(_key, _val) values (?, ?)").setArgs(id, 1)); + + assertEquals(1, (int)p.get(id)); + } }
