From d0de8df20386bb02595246bd26629b379746a18c Mon Sep 17 00:00:00 2001 From: Luigi Dell'Aquila Date: Tue, 6 Nov 2018 11:51:56 +0100 Subject: [PATCH] Fix insert on LINKMAP with subqueries Resolves: #8646 --- .../orient/core/record/impl/ODocument.java | 42 +++++++++++++++---- .../OInsertStatementExecutionTest.java | 32 +++++++++++--- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java b/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java index 369e70ae881..02a12e20107 100755 --- a/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java +++ b/core/src/main/java/com/orientechnologies/orient/core/record/impl/ODocument.java @@ -46,6 +46,7 @@ import com.orientechnologies.orient.core.serialization.serializer.record.ORecordSerializerFactory; import com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetwork; import com.orientechnologies.orient.core.sql.OSQLHelper; +import com.orientechnologies.orient.core.sql.executor.OResult; import com.orientechnologies.orient.core.sql.filter.OSQLPredicate; import com.orientechnologies.orient.core.storage.OBasicTransaction; import com.orientechnologies.orient.core.storage.OStorage; @@ -2609,17 +2610,43 @@ protected void autoConvertValues() { convertToEmbeddedType(prop); continue; } - if (linkedType == null) - continue; final ODocumentEntry entry = _fields.get(prop.getName()); - if (entry == null) + if (entry == null) { continue; - if (!entry.created && !entry.changed) + } + if (!entry.created && !entry.changed) { continue; + } Object value = entry.value; - if (value == null) + if (value == null) { continue; + } try { + if (type == OType.LINKMAP) { + if (entry.value instanceof Map) { + Map map = (Map) entry.value; + Map newMap = new ORecordLazyMap(this); + boolean changed = false; + for (Entry stringObjectEntry : map.entrySet()) { + Object val = stringObjectEntry.getValue(); + if (OMultiValue.isMultiValue(val) && OMultiValue.getSize(val) == 1) { + val = OMultiValue.getFirstValue(val); + if (val instanceof OResult) { + val = ((OResult) val).getIdentity().orElse(null); + } + changed = true; + } + newMap.put(stringObjectEntry.getKey(), val); + } + if (changed) { + entry.value = newMap; + } + } + } + + if (linkedType == null) + continue; + if (type == OType.EMBEDDEDLIST) { OTrackedList list = new OTrackedList<>(this); Collection values = (Collection) value; @@ -3061,9 +3088,10 @@ private void convertFieldsToClass(final OClass _clazz) { if (entry != null && entry.exist()) { if (entry.type == null || entry.type != prop.getType()) { boolean preChanged = entry.changed; - boolean preCreated = entry.created;; + boolean preCreated = entry.created; + ; field(prop.getName(), entry.value, prop.getType()); - if(_recordId.isNew()){ + if (_recordId.isNew()) { entry.changed = preChanged; entry.created = preCreated; } diff --git a/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OInsertStatementExecutionTest.java b/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OInsertStatementExecutionTest.java index 774fe0ca19b..db90815f6f9 100644 --- a/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OInsertStatementExecutionTest.java +++ b/core/src/test/java/com/orientechnologies/orient/core/sql/executor/OInsertStatementExecutionTest.java @@ -9,10 +9,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import static com.orientechnologies.orient.core.sql.executor.ExecutionPlanPrintUtils.printExecutionPlan; @@ -351,8 +348,8 @@ public void testNestedInsert() { String className = "testNestedInsert"; db.getMetadata().getSchema().createClass(className); - OResultSet result = db - .command("insert into " + className + " set name = 'parent', children = (INSERT INTO " + className + " SET name = 'child')"); + OResultSet result = db.command( + "insert into " + className + " set name = 'parent', children = (INSERT INTO " + className + " SET name = 'child')"); result.close(); @@ -369,4 +366,27 @@ public void testNestedInsert() { result.close(); } + @Test + public void testLinkMapWithSubqueries() { + String className = "testLinkMapWithSubqueries"; + String itemclassName = "testLinkMapWithSubqueriesTheItem"; + + db.command("CREATE CLASS " + className); + db.command("CREATE CLASS " + itemclassName); + db.command("CREATE PROPERTY " + className + ".mymap LINKMAP " + itemclassName); + + db.command("INSERT INTO " + itemclassName + " (name) VALUES ('test')"); + db.command("INSERT INTO " + className + " (mymap) VALUES ({'A-1': (SELECT FROM " + itemclassName + " WHERE name = 'test')})"); + + OResultSet result = db.query("SELECT FROM " + className); + + OResult item = result.next(); + Map theMap = item.getProperty("mymap"); + Assert.assertEquals(1, theMap.size()); + Assert.assertNotNull(theMap.get("A-1")); + + Assert.assertFalse(result.hasNext()); + result.close(); + } + }