This is an automated email from the ASF dual-hosted git repository.
tkalkirill pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new e167c685ab IGNITE-19693 getAll does not preserve order and does not
return nulls for missing keys (#2233)
e167c685ab is described below
commit e167c685ab0088e78f628bc589ea6d1881971427
Author: Kirill Tkalenko <[email protected]>
AuthorDate: Mon Jun 26 10:32:04 2023 +0300
IGNITE-19693 getAll does not preserve order and does not return nulls for
missing keys (#2233)
---
.../java/org/apache/ignite/table/RecordView.java | 11 ++--
.../internal/client/table/ClientKeyValueView.java | 11 ++--
.../client/table/ClientRecordBinaryView.java | 13 ++---
.../client/table/ClientRecordSerializer.java | 3 +-
.../internal/client/table/ClientRecordView.java | 13 ++---
.../client/table/ClientTupleSerializer.java | 3 +-
.../apache/ignite/client/ClientRecordViewTest.java | 12 +++--
.../ignite/client/fakes/FakeInternalTable.java | 10 ++--
.../ignite/client/fakes/FakeSchemaRegistry.java | 10 ++--
.../client-test/key_value_binary_view_test.cpp | 61 ++++++++++++----------
.../cpp/tests/client-test/key_value_view_test.cpp | 47 +++++++++++------
.../tests/client-test/record_binary_view_test.cpp | 61 ++++++++++++----------
.../cpp/tests/client-test/record_view_test.cpp | 53 +++++++++++--------
.../cpp/tests/client-test/transactions_test.cpp | 6 ++-
.../Table/RecordViewBinaryTests.cs | 13 +++--
.../Table/RecordViewPocoTests.cs | 13 +++--
.../Transactions/TransactionsTests.cs | 2 +-
.../runner/app/ItTableApiContractTest.java | 13 +++--
.../app/client/ItThinClientTransactionsTest.java | 4 +-
.../ignite/internal/schema/SchemaRegistry.java | 5 +-
.../schema/registry/SchemaRegistryImpl.java | 13 ++---
modules/table/build.gradle | 1 +
.../ignite/internal/table/InternalTable.java | 14 +++--
.../internal/table/KeyValueBinaryViewImpl.java | 4 +-
.../ignite/internal/table/KeyValueViewImpl.java | 4 +-
.../internal/table/RecordBinaryViewImpl.java | 22 ++++----
.../ignite/internal/table/RecordViewImpl.java | 25 +++++----
.../distributed/storage/InternalTableImpl.java | 6 +--
.../table/RecordBinaryViewOperationsTest.java | 24 +++------
.../internal/table/RecordViewOperationsTest.java | 6 +--
.../ignite/internal/table/TxAbstractTest.java | 24 ++++-----
.../table/impl/DummySchemaManagerImpl.java | 10 ++--
32 files changed, 292 insertions(+), 225 deletions(-)
diff --git a/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
b/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
index 4d756edf0d..0906b5fb5c 100644
--- a/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
+++ b/modules/api/src/main/java/org/apache/ignite/table/RecordView.java
@@ -18,6 +18,7 @@
package org.apache.ignite.table;
import java.util.Collection;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.apache.ignite.tx.Transaction;
import org.jetbrains.annotations.NotNull;
@@ -55,18 +56,20 @@ public interface RecordView<R> extends
DataStreamerTarget<R> {
* @param keyRecs Records with key columns set. The records cannot be
{@code null}.
* @return Records with all columns filled from the table. The order of
collection elements is
* guaranteed to be the same as the order of {@code keyRecs}. If a
record does not exist, the
- * element at the corresponding index of the resulting collection is
null.
+ * element at the corresponding index of the resulting collection is
{@code null}.
*/
- Collection<R> getAll(@Nullable Transaction tx, @NotNull Collection<R>
keyRecs);
+ List<R> getAll(@Nullable Transaction tx, Collection<R> keyRecs);
/**
* Asynchronously gets records from a table.
*
* @param tx Transaction or {@code null} to auto-commit.
* @param keyRecs Records with the key columns set. The records cannot be
{@code null}.
- * @return Future that represents the pending completion of the operation.
+ * @return Future that will return records with all columns filled from
the table. The order of collection elements is
+ * guaranteed to be the same as the order of {@code keyRecs}. If a
record does not exist, the
+ * element at the corresponding index of the resulting collection is
{@code null}.
*/
- @NotNull CompletableFuture<Collection<R>> getAllAsync(@Nullable
Transaction tx, @NotNull Collection<R> keyRecs);
+ CompletableFuture<List<R>> getAllAsync(@Nullable Transaction tx,
Collection<R> keyRecs);
/**
* Inserts a record into a table, if it does not exist, or replaces an
existing one.
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
index 408a71cfb4..09b3a764ec 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientKeyValueView.java
@@ -464,11 +464,12 @@ public class ClientKeyValueView<K, V> implements
KeyValueView<K, V> {
try {
for (int i = 0; i < cnt; i++) {
- in.unpackBoolean(); // TODO: Optimize (IGNITE-16022).
-
- var tupleReader = new
BinaryTupleReader(schema.columns().length, in.readBinaryUnsafe());
- var reader = new ClientMarshallerReader(tupleReader);
- res.put((K) keyMarsh.readObject(reader, null), (V)
valMarsh.readObject(reader, null));
+ // TODO: Optimize (IGNITE-16022).
+ if (in.unpackBoolean()) {
+ var tupleReader = new
BinaryTupleReader(schema.columns().length, in.readBinaryUnsafe());
+ var reader = new ClientMarshallerReader(tupleReader);
+ res.put((K) keyMarsh.readObject(reader, null), (V)
valMarsh.readObject(reader, null));
+ }
}
return res;
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
index 40b4294f38..f48a2c2a18 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordBinaryView.java
@@ -17,10 +17,12 @@
package org.apache.ignite.internal.client.table;
+import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.apache.ignite.internal.client.ClientUtils.sync;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Flow.Publisher;
@@ -76,19 +78,17 @@ public class ClientRecordBinaryView implements
RecordView<Tuple> {
ClientTupleSerializer.getPartitionAwarenessProvider(tx,
keyRec));
}
- /** {@inheritDoc} */
@Override
- public Collection<Tuple> getAll(@Nullable Transaction tx, @NotNull
Collection<Tuple> keyRecs) {
+ public List<Tuple> getAll(@Nullable Transaction tx, Collection<Tuple>
keyRecs) {
return sync(getAllAsync(tx, keyRecs));
}
- /** {@inheritDoc} */
@Override
- public @NotNull CompletableFuture<Collection<Tuple>> getAllAsync(@Nullable
Transaction tx, @NotNull Collection<Tuple> keyRecs) {
+ public CompletableFuture<List<Tuple>> getAllAsync(@Nullable Transaction
tx, Collection<Tuple> keyRecs) {
Objects.requireNonNull(keyRecs);
if (keyRecs.isEmpty()) {
- return CompletableFuture.completedFuture(Collections.emptyList());
+ return completedFuture(Collections.emptyList());
}
return tbl.doSchemaOutInOpAsync(
@@ -96,7 +96,8 @@ public class ClientRecordBinaryView implements
RecordView<Tuple> {
(s, w) -> ser.writeTuples(tx, keyRecs, s, w, true),
ClientTupleSerializer::readTuplesNullable,
Collections.emptyList(),
- ClientTupleSerializer.getPartitionAwarenessProvider(tx,
keyRecs.iterator().next()));
+ ClientTupleSerializer.getPartitionAwarenessProvider(tx,
keyRecs.iterator().next())
+ );
}
/** {@inheritDoc} */
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordSerializer.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordSerializer.java
index ba0901f571..975606762b 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordSerializer.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordSerializer.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import org.apache.ignite.internal.binarytuple.BinaryTupleBuilder;
import org.apache.ignite.internal.binarytuple.BinaryTupleReader;
import org.apache.ignite.internal.client.PayloadOutputChannel;
@@ -166,7 +167,7 @@ public class ClientRecordSerializer<R> {
}
}
- Collection<R> readRecs(ClientSchema schema, ClientMessageUnpacker in,
boolean nullable, TuplePart part) {
+ List<R> readRecs(ClientSchema schema, ClientMessageUnpacker in, boolean
nullable, TuplePart part) {
var cnt = in.unpackInt();
if (cnt == 0) {
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
index 42f9358e65..35d6a68afa 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientRecordView.java
@@ -17,10 +17,12 @@
package org.apache.ignite.internal.client.table;
+import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.apache.ignite.internal.client.ClientUtils.sync;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Flow.Publisher;
@@ -76,19 +78,17 @@ public class ClientRecordView<R> implements RecordView<R> {
ClientTupleSerializer.getPartitionAwarenessProvider(tx,
ser.mapper(), keyRec));
}
- /** {@inheritDoc} */
@Override
- public Collection<R> getAll(@Nullable Transaction tx, @NotNull
Collection<R> keyRecs) {
+ public List<R> getAll(@Nullable Transaction tx, Collection<R> keyRecs) {
return sync(getAllAsync(tx, keyRecs));
}
- /** {@inheritDoc} */
@Override
- public @NotNull CompletableFuture<Collection<R>> getAllAsync(@Nullable
Transaction tx, @NotNull Collection<R> keyRecs) {
+ public CompletableFuture<List<R>> getAllAsync(@Nullable Transaction tx,
Collection<R> keyRecs) {
Objects.requireNonNull(keyRecs);
if (keyRecs.isEmpty()) {
- return CompletableFuture.completedFuture(Collections.emptyList());
+ return completedFuture(Collections.emptyList());
}
return tbl.doSchemaOutInOpAsync(
@@ -96,7 +96,8 @@ public class ClientRecordView<R> implements RecordView<R> {
(s, w) -> ser.writeRecs(tx, keyRecs, s, w, TuplePart.KEY),
(s, r) -> ser.readRecs(s, r, true, TuplePart.KEY_AND_VAL),
Collections.emptyList(),
- ClientTupleSerializer.getPartitionAwarenessProvider(tx,
ser.mapper(), keyRecs.iterator().next()));
+ ClientTupleSerializer.getPartitionAwarenessProvider(tx,
ser.mapper(), keyRecs.iterator().next())
+ );
}
/** {@inheritDoc} */
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
index e6e9cc1738..c0ef66a94f 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTupleSerializer.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
@@ -299,7 +300,7 @@ public class ClientTupleSerializer {
return res;
}
- static Collection<Tuple> readTuplesNullable(ClientSchema schema,
ClientMessageUnpacker in) {
+ static List<Tuple> readTuplesNullable(ClientSchema schema,
ClientMessageUnpacker in) {
var cnt = in.unpackInt();
var res = new ArrayList<Tuple>(cnt);
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
index d98a924f6c..a6e52f354c 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/ClientRecordViewTest.java
@@ -251,16 +251,17 @@ public class ClientRecordViewTest extends
AbstractClientTableTest {
PersonPojo[] res = pojoView.getAll(null, keys).toArray(new
PersonPojo[0]);
- assertEquals(2, res.length);
+ assertEquals(3, res.length);
assertNotNull(res[0]);
- assertNotNull(res[1]);
+ assertNull(res[1]);
+ assertNotNull(res[2]);
assertEquals(DEFAULT_ID, res[0].id);
assertEquals(DEFAULT_NAME, res[0].name);
- assertEquals(100L, res[1].id);
- assertEquals("100", res[1].name);
+ assertEquals(100L, res[2].id);
+ assertEquals("100", res[2].name);
}
@Test
@@ -273,7 +274,8 @@ public class ClientRecordViewTest extends
AbstractClientTableTest {
String[] res = primitiveView.getAll(null, List.of("a", "b",
"c")).toArray(new String[0]);
assertEquals("a", res[0]);
- assertEquals("c", res[1]);
+ assertNull(res[1]);
+ assertEquals("c", res[2]);
}
@Test
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeInternalTable.java
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeInternalTable.java
index a8e27e60e4..614e498676 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeInternalTable.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeInternalTable.java
@@ -17,6 +17,8 @@
package org.apache.ignite.client.fakes;
+import static java.util.concurrent.CompletableFuture.completedFuture;
+
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.BitSet;
@@ -123,7 +125,7 @@ public class FakeInternalTable implements InternalTable {
/** {@inheritDoc} */
@Override
- public CompletableFuture<Collection<BinaryRow>>
getAll(Collection<BinaryRowEx> keyRows,
+ public CompletableFuture<List<BinaryRow>> getAll(Collection<BinaryRowEx>
keyRows,
@Nullable InternalTransaction tx) {
var res = new ArrayList<BinaryRow>();
@@ -132,15 +134,17 @@ public class FakeInternalTable implements InternalTable {
if (val != null) {
res.add(val.getNow(null));
+ } else {
+ res.add(null);
}
}
onDataAccess("getAll", keyRows);
- return CompletableFuture.completedFuture(res);
+ return completedFuture(res);
}
@Override
- public CompletableFuture<Collection<BinaryRow>> getAll(
+ public CompletableFuture<List<BinaryRow>> getAll(
Collection<BinaryRowEx> keyRows,
HybridTimestamp readTimestamp,
ClusterNode recipientNode
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeSchemaRegistry.java
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeSchemaRegistry.java
index 899bd0a32d..21b8e74a26 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeSchemaRegistry.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeSchemaRegistry.java
@@ -17,12 +17,13 @@
package org.apache.ignite.client.fakes;
+import static java.util.stream.Collectors.toList;
+
import java.util.Collection;
-import java.util.Objects;
+import java.util.List;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.Function;
-import java.util.stream.Collectors;
import org.apache.ignite.internal.schema.BinaryRow;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.SchemaRegistry;
@@ -127,9 +128,8 @@ public class FakeSchemaRegistry implements SchemaRegistry {
return new Row(schema(row.schemaVersion()), row);
}
- /** {@inheritDoc} */
@Override
- public Collection<Row> resolve(Collection<BinaryRow> rows) {
- return
rows.stream().filter(Objects::nonNull).map(this::resolve).collect(Collectors.toList());
+ public List<Row> resolve(Collection<BinaryRow> rows) {
+ return rows.stream().map(binaryRow -> binaryRow == null ? null :
resolve(binaryRow)).collect(toList());
}
}
diff --git
a/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
b/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
index e6ef6d7646..30930c8066 100644
--- a/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/key_value_binary_view_test.cpp
@@ -160,7 +160,10 @@ TEST_F(key_value_binary_view_test, get_all_empty) {
TEST_F(key_value_binary_view_test, get_all_nonexisting) {
auto res = kv_view.get_all(nullptr, {get_tuple(-42)});
- ASSERT_TRUE(res.empty());
+ ASSERT_FALSE(res.empty());
+
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front(), std::nullopt);
}
TEST_F(key_value_binary_view_test, put_all_empty_no_throw) {
@@ -168,11 +171,11 @@ TEST_F(key_value_binary_view_test,
put_all_empty_no_throw) {
}
TEST_F(key_value_binary_view_test, put_all_get_all) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<std::pair<ignite_tuple, ignite_tuple>> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(get_tuple(i), get_tuple("Val" +
std::to_string(i)));
std::vector<ignite_tuple> keys;
@@ -182,26 +185,28 @@ TEST_F(key_value_binary_view_test, put_all_get_all) {
kv_view.put_all(nullptr, records);
auto res = kv_view.get_all(nullptr, keys);
- // TODO: Key order should be preserved by the server (IGNITE-16004).
- EXPECT_EQ(res.size(), 2);
-
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ(2, res[0]->column_count());
- EXPECT_EQ(9, res[0]->get<int64_t>("key"));
- EXPECT_EQ("Val9", res[0]->get<std::string>("val"));
+ ASSERT_EQ(res.size(), keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i].get<std::int64_t>(0);
+ auto val = res[i];
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ(2, res[1]->column_count());
- EXPECT_EQ(10, res[1]->get<int64_t>("key"));
- EXPECT_EQ("Val10", res[1]->get<std::string>("val"));
+ if (key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key;
+ EXPECT_EQ(2, val->column_count());
+ EXPECT_EQ(key, val->get<std::int64_t>("key"));
+ EXPECT_EQ("Val" + std::to_string(key),
val->get<std::string>("val"));
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key << ", Res = " <<
val->get<std::string>("val");
+ }
+ }
}
TEST_F(key_value_binary_view_test, put_all_get_all_async) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<std::pair<ignite_tuple, ignite_tuple>> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(get_tuple(i), get_tuple("Val" +
std::to_string(i)));
std::vector<ignite_tuple> keys;
@@ -214,23 +219,25 @@ TEST_F(key_value_binary_view_test, put_all_get_all_async)
{
if (!check_and_set_operation_error(*all_done, res))
return;
- // TODO: Key order should be preserved by the server (IGNITE-16004).
kv_view.get_all_async(nullptr, keys, [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
});
auto res = all_done->get_future().get();
- EXPECT_EQ(res.size(), 2);
-
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ(2, res[0]->column_count());
- EXPECT_EQ(9, res[0]->get<int64_t>("key"));
- EXPECT_EQ("Val9", res[0]->get<std::string>("val"));
+ ASSERT_EQ(res.size(), keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i].get<std::int64_t>(0);
+ auto val = res[i];
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ(2, res[1]->column_count());
- EXPECT_EQ(10, res[1]->get<int64_t>("key"));
- EXPECT_EQ("Val10", res[1]->get<std::string>("val"));
+ if (key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key;
+ EXPECT_EQ(2, val->column_count());
+ EXPECT_EQ(key, val->get<std::int64_t>("key"));
+ EXPECT_EQ("Val" + std::to_string(key),
val->get<std::string>("val"));
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key << ", Res = " <<
val->get<std::string>("val");
+ }
+ }
}
TEST_F(key_value_binary_view_test, get_and_put_new_record) {
diff --git a/modules/platforms/cpp/tests/client-test/key_value_view_test.cpp
b/modules/platforms/cpp/tests/client-test/key_value_view_test.cpp
index 6aa892d873..f3a7dedc5a 100644
--- a/modules/platforms/cpp/tests/client-test/key_value_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/key_value_view_test.cpp
@@ -176,7 +176,10 @@ TEST_F(key_value_view_test, get_all_empty) {
TEST_F(key_value_view_test, get_all_nonexisting) {
auto res = kv_view.get_all(nullptr, {test_key_type(-42)});
- ASSERT_TRUE(res.empty());
+ ASSERT_FALSE(res.empty());
+
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front(), std::nullopt);
}
TEST_F(key_value_view_test, put_all_empty_no_throw) {
@@ -184,11 +187,11 @@ TEST_F(key_value_view_test, put_all_empty_no_throw) {
}
TEST_F(key_value_view_test, put_all_get_all) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<std::pair<test_key_type, test_value_type>> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(i, "Val" + std::to_string(i));
std::vector<test_key_type> keys;
@@ -198,22 +201,27 @@ TEST_F(key_value_view_test, put_all_get_all) {
kv_view.put_all(nullptr, records);
auto res = kv_view.get_all(nullptr, keys);
- // TODO: Key order should be preserved by the server (IGNITE-16004).
- EXPECT_EQ(res.size(), 2);
+ ASSERT_EQ(res.size(), keys.size());
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ("Val9", res[0]->val);
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i];
+ auto val = res[i];
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ("Val10", res[1]->val);
+ if (key.key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key.key;
+ EXPECT_EQ("Val" + std::to_string(key.key), val->val);
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key.key << ", Res = "
<< val->val;
+ }
+ }
}
TEST_F(key_value_view_test, put_all_get_all_async) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<std::pair<test_key_type, test_value_type>> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(i, "Val" + std::to_string(i));
std::vector<test_key_type> keys;
@@ -226,19 +234,24 @@ TEST_F(key_value_view_test, put_all_get_all_async) {
if (!check_and_set_operation_error(*all_done, res))
return;
- // TODO: Key order should be preserved by the server (IGNITE-16004).
kv_view.get_all_async(nullptr, keys, [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
});
auto res = all_done->get_future().get();
- EXPECT_EQ(res.size(), 2);
+ ASSERT_EQ(res.size(), keys.size());
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ("Val9", res[0]->val);
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i];
+ auto val = res[i];
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ("Val10", res[1]->val);
+ if (key.key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key.key;
+ EXPECT_EQ("Val" + std::to_string(key.key), val->val);
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key.key << ", Res = "
<< val->val;
+ }
+ }
}
TEST_F(key_value_view_test, get_and_put_new_record) {
diff --git
a/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
b/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
index fd95e93e61..b2376df3c1 100644
--- a/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
@@ -147,7 +147,10 @@ TEST_F(record_binary_view_test, get_all_empty) {
TEST_F(record_binary_view_test, get_all_nonexisting) {
auto res = tuple_view.get_all(nullptr, {get_tuple(-42)});
- ASSERT_TRUE(res.empty());
+ ASSERT_FALSE(res.empty());
+
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front(), std::nullopt);
}
TEST_F(record_binary_view_test, upsert_all_empty_no_throw) {
@@ -155,11 +158,11 @@ TEST_F(record_binary_view_test,
upsert_all_empty_no_throw) {
}
TEST_F(record_binary_view_test, upsert_all_get_all) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<ignite_tuple> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(get_tuple(i, "Val" + std::to_string(i)));
std::vector<ignite_tuple> keys;
@@ -169,26 +172,28 @@ TEST_F(record_binary_view_test, upsert_all_get_all) {
tuple_view.upsert_all(nullptr, records);
auto res = tuple_view.get_all(nullptr, keys);
- // TODO: Key order should be preserved by the server (IGNITE-16004).
- EXPECT_EQ(res.size(), 2);
+ ASSERT_EQ(res.size(), keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i].get<std::int64_t>(0);
+ auto val = res[i];
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ(2, res[0]->column_count());
- EXPECT_EQ(9, res[0]->get<int64_t>("key"));
- EXPECT_EQ("Val9", res[0]->get<std::string>("val"));
-
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ(2, res[1]->column_count());
- EXPECT_EQ(10, res[1]->get<int64_t>("key"));
- EXPECT_EQ("Val10", res[1]->get<std::string>("val"));
+ if (key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key;
+ EXPECT_EQ(2, val->column_count());
+ EXPECT_EQ(key, val->get<std::int64_t>("key"));
+ EXPECT_EQ("Val" + std::to_string(key),
val->get<std::string>("val"));
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key << ", Res = " <<
val->get<std::string>("val");
+ }
+ }
}
TEST_F(record_binary_view_test, upsert_all_get_all_async) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<ignite_tuple> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(get_tuple(i, "Val" + std::to_string(i)));
std::vector<ignite_tuple> keys;
@@ -201,23 +206,25 @@ TEST_F(record_binary_view_test, upsert_all_get_all_async)
{
if (!check_and_set_operation_error(*all_done, res))
return;
- // TODO: Key order should be preserved by the server (IGNITE-16004).
tuple_view.get_all_async(nullptr, keys, [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
});
auto res = all_done->get_future().get();
- EXPECT_EQ(res.size(), 2);
+ ASSERT_EQ(res.size(), keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i].get<std::int64_t>(0);
+ auto val = res[i];
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ(2, res[0]->column_count());
- EXPECT_EQ(9, res[0]->get<int64_t>("key"));
- EXPECT_EQ("Val9", res[0]->get<std::string>("val"));
-
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ(2, res[1]->column_count());
- EXPECT_EQ(10, res[1]->get<int64_t>("key"));
- EXPECT_EQ("Val10", res[1]->get<std::string>("val"));
+ if (key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key;
+ EXPECT_EQ(2, val->column_count());
+ EXPECT_EQ(key, val->get<std::int64_t>("key"));
+ EXPECT_EQ("Val" + std::to_string(key),
val->get<std::string>("val"));
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key << ", Res = " <<
val->get<std::string>("val");
+ }
+ }
}
TEST_F(record_binary_view_test, get_and_upsert_new_record) {
diff --git a/modules/platforms/cpp/tests/client-test/record_view_test.cpp
b/modules/platforms/cpp/tests/client-test/record_view_test.cpp
index 91b7c24624..0fdcc5ab17 100644
--- a/modules/platforms/cpp/tests/client-test/record_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/record_view_test.cpp
@@ -286,7 +286,10 @@ TEST_F(record_view_test, get_all_empty) {
TEST_F(record_view_test, get_all_nonexisting) {
auto res = view.get_all(nullptr, {test_type(-42)});
- ASSERT_TRUE(res.empty());
+ ASSERT_FALSE(res.empty());
+
+ EXPECT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front(), std::nullopt);
}
TEST_F(record_view_test, upsert_all_empty_no_throw) {
@@ -294,11 +297,11 @@ TEST_F(record_view_test, upsert_all_empty_no_throw) {
}
TEST_F(record_view_test, upsert_all_get_all) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<test_type> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(i, "Val" + std::to_string(i));
std::vector<test_type> keys;
@@ -308,24 +311,28 @@ TEST_F(record_view_test, upsert_all_get_all) {
view.upsert_all(nullptr, records);
auto res = view.get_all(nullptr, keys);
- // TODO: Key order should be preserved by the server (IGNITE-16004).
- EXPECT_EQ(res.size(), 2);
+ ASSERT_EQ(res.size(), keys.size());
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ(9, res[0]->key);
- EXPECT_EQ("Val9", res[0]->val);
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i];
+ auto val = res[i];
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ(10, res[1]->key);
- EXPECT_EQ("Val10", res[1]->val);
+ if (key.key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key.key;
+ EXPECT_EQ(key.key, val->key);
+ EXPECT_EQ("Val" + std::to_string(key.key), val->val);
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key.key << ", Res = "
<< val->val;
+ }
+ }
}
TEST_F(record_view_test, upsert_all_get_all_async) {
- static constexpr std::size_t records_num = 10;
+ static constexpr std::int64_t records_num = 10;
std::vector<test_type> records;
records.reserve(records_num);
- for (std::int64_t i = 1; i < 1 + std::int64_t(records_num); ++i)
+ for (std::int64_t i = 1; i < 1 + records_num; ++i)
records.emplace_back(i, "Val" + std::to_string(i));
std::vector<test_type> keys;
@@ -338,21 +345,25 @@ TEST_F(record_view_test, upsert_all_get_all_async) {
if (!check_and_set_operation_error(*all_done, res))
return;
- // TODO: Key order should be preserved by the server (IGNITE-16004).
view.get_all_async(nullptr, keys, [&](auto res) {
result_set_promise(*all_done, std::move(res)); });
});
auto res = all_done->get_future().get();
- EXPECT_EQ(res.size(), 2);
+ ASSERT_EQ(res.size(), keys.size());
- ASSERT_TRUE(res[0].has_value());
- EXPECT_EQ(9, res[0]->key);
- EXPECT_EQ("Val9", res[0]->val);
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ auto key = keys[i];
+ auto val = res[i];
- ASSERT_TRUE(res[1].has_value());
- EXPECT_EQ(10, res[1]->key);
- EXPECT_EQ("Val10", res[1]->val);
+ if (key.key <= records_num) {
+ ASSERT_TRUE(val.has_value()) << "Key = " << key.key;
+ EXPECT_EQ(key.key, val->key);
+ EXPECT_EQ("Val" + std::to_string(key.key), val->val);
+ } else {
+ ASSERT_FALSE(val.has_value()) << "Key = " << key.key << ", Res = "
<< val->val;
+ }
+ }
}
TEST_F(record_view_test, get_and_upsert_new_record) {
diff --git a/modules/platforms/cpp/tests/client-test/transactions_test.cpp
b/modules/platforms/cpp/tests/client-test/transactions_test.cpp
index 9b70c4b012..7c7243a40e 100644
--- a/modules/platforms/cpp/tests/client-test/transactions_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/transactions_test.cpp
@@ -211,7 +211,8 @@ TEST_F(transactions_test, record_view_upsert_all) {
auto values2 = record_view.get_all(nullptr, {get_tuple(42)});
- ASSERT_TRUE(values2.empty());
+ ASSERT_EQ(1, values2.size());
+ EXPECT_FALSE(values2.front().has_value());
}
TEST_F(transactions_test, record_view_get_and_upsert) {
@@ -279,7 +280,8 @@ TEST_F(transactions_test, record_view_insert_all) {
auto values2 = record_view.get_all(nullptr, {get_tuple(42)});
- ASSERT_TRUE(values2.empty());
+ ASSERT_EQ(1, values2.size());
+ EXPECT_FALSE(values2.front().has_value());
}
TEST_F(transactions_test, record_view_replace) {
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewBinaryTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewBinaryTests.cs
index 59d972b141..1c82e273d7 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewBinaryTests.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewBinaryTests.cs
@@ -360,25 +360,28 @@ namespace Apache.Ignite.Tests.Table
await TupleView.UpsertAllAsync(null, records);
- // TODO: Key order should be preserved by the server
(IGNITE-16004).
var res = await TupleView.GetAllAsync(null, Enumerable.Range(9,
4).Select(x => GetTuple(x)));
- var resArr = res.OrderBy(x => x.Value[0]).ToArray();
+ var resArr = res.ToArray();
- Assert.AreEqual(2, res.Count);
+ Assert.AreEqual(4, res.Count);
Assert.AreEqual(9, resArr[0].Value[0]);
Assert.AreEqual("9", resArr[0].Value[1]);
Assert.AreEqual(10, resArr[1].Value[0]);
Assert.AreEqual("10", resArr[1].Value[1]);
+
+ Assert.IsFalse(resArr[2].HasValue);
+ Assert.IsFalse(resArr[3].HasValue);
}
[Test]
- public async Task TestGetAllNonExistentKeysReturnsEmptyList()
+ public async Task TestGetAllNonExistentKeysReturnsListWithNoValue()
{
var res = await TupleView.GetAllAsync(null, new[] { GetTuple(-100)
});
- Assert.AreEqual(0, res.Count);
+ Assert.AreEqual(1, res.Count);
+ Assert.IsFalse(res[0].HasValue);
}
[Test]
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewPocoTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewPocoTests.cs
index 98056ed6f1..ee2ba78e62 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewPocoTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Table/RecordViewPocoTests.cs
@@ -383,25 +383,28 @@ namespace Apache.Ignite.Tests.Table
await PocoView.UpsertAllAsync(null, records);
- // TODO: Key order should be preserved by the server
(IGNITE-16004).
var res = await PocoView.GetAllAsync(null, Enumerable.Range(9,
4).Select(x => GetPoco(x)));
- var resArr = res.OrderBy(x => x.Value.Key).ToArray();
+ var resArr = res.ToArray();
- Assert.AreEqual(2, res.Count);
+ Assert.AreEqual(4, res.Count);
Assert.AreEqual(9, resArr[0].Value.Key);
Assert.AreEqual("9", resArr[0].Value.Val);
Assert.AreEqual(10, resArr[1].Value.Key);
Assert.AreEqual("10", resArr[1].Value.Val);
+
+ Assert.IsFalse(resArr[2].HasValue);
+ Assert.IsFalse(resArr[3].HasValue);
}
[Test]
- public async Task TestGetAllNonExistentKeysReturnsEmptyList()
+ public async Task TestGetAllNonExistentKeysReturnsListWithNoValue()
{
var res = await PocoView.GetAllAsync(null, new[] { GetPoco(-100)
});
- Assert.AreEqual(0, res.Count);
+ Assert.AreEqual(1, res.Count);
+ Assert.IsFalse(res[0].HasValue);
}
[Test]
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs
index fb499064bf..c493020f54 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Tests/Transactions/TransactionsTests.cs
@@ -58,7 +58,7 @@ namespace Apache.Ignite.Tests.Transactions
Assert.IsFalse(await TupleView.DeleteAsync(tx, key));
await TupleView.UpsertAllAsync(tx, new[] { GetTuple(1, "6"),
GetTuple(2, "7") });
- Assert.AreEqual(2, (await TupleView.GetAllAsync(tx, new[] { key,
GetTuple(2), GetTuple(3) })).Count);
+ Assert.AreEqual(3, (await TupleView.GetAllAsync(tx, new[] { key,
GetTuple(2), GetTuple(3) })).Count);
var insertAllRes = await TupleView.InsertAllAsync(tx, new[] {
GetTuple(1, "8"), GetTuple(3, "9") });
Assert.AreEqual(GetTuple(1, "6"), (await TupleView.GetAsync(tx,
key)).Value);
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
index d123b28903..91da7e94e7 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
@@ -23,6 +23,7 @@ import static
org.apache.ignite.internal.schema.testutils.SchemaConfigurationCon
import static org.apache.ignite.internal.testframework.IgniteTestUtils.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -255,6 +256,11 @@ public class ItTableApiContractTest extends
ClusterPerClassIntegrationTest {
public void testGetAll() {
RecordView<Tuple> tbl = ignite.tables().table(TABLE_NAME).recordView();
+ assertThat(
+ tbl.getAll(null, List.of(Tuple.create().set("name", "id_0"))),
+ contains(nullValue())
+ );
+
var recs = IntStream.range(0, 5)
.mapToObj(i -> Tuple.create().set("name", "id_" + i *
2).set("balance", i * 2))
.collect(toList());
@@ -265,12 +271,11 @@ public class ItTableApiContractTest extends
ClusterPerClassIntegrationTest {
.mapToObj(i -> Tuple.create().set("name", "id_" + i))
.collect(toList());
- List<Tuple> res = (List<Tuple>) tbl.getAll(null, keys);
+ List<Tuple> res = tbl.getAll(null, keys);
- // TODO: IGNITE-19693 should be: "id_0", null, "id_2", null, "id_4",
null, "id_6", null, "id_8", null
assertThat(
- res.stream().map(tuple ->
tuple.stringValue(0)).collect(toList()),
- contains("id_0", "id_2", "id_4", "id_6", "id_8")
+ res.stream().map(tuple -> tuple == null ? null :
tuple.stringValue(0)).collect(toList()),
+ contains("id_0", null, "id_2", null, "id_4", null, "id_6",
null, "id_8", null)
);
}
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
index 05aa8da742..b0ac1d5635 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientTransactionsTest.java
@@ -123,7 +123,7 @@ public class ItThinClientTransactionsTest extends
ItAbstractThinClientTest {
assertFalse(recordView.delete(tx, key));
recordView.upsertAll(tx, List.of(rec(1, "6"), rec(2, "7")));
- assertEquals(2, recordView.getAll(tx, List.of(key, rec(2, null),
rec(3, null))).size());
+ assertEquals(3, recordView.getAll(tx, List.of(key, rec(2, null),
rec(3, null))).size());
tx.rollback();
assertEquals(rec(1, "1"), recordView.get(null, key));
@@ -149,7 +149,7 @@ public class ItThinClientTransactionsTest extends
ItAbstractThinClientTest {
assertFalse(recordView.delete(tx, key));
recordView.upsertAll(tx, List.of(kv(1, "6"), kv(2, "7")));
- assertEquals(2, recordView.getAll(tx, List.of(key, key(2),
key(3))).size());
+ assertEquals(3, recordView.getAll(tx, List.of(key, key(2),
key(3))).size());
tx.rollback();
assertEquals(kv(1, "1"), recordView.get(null, key));
diff --git
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
index fd279935f2..2e8ecd8918 100644
---
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
+++
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.schema;
import java.util.Collection;
+import java.util.List;
import org.apache.ignite.internal.schema.registry.SchemaRegistryException;
import org.apache.ignite.internal.schema.row.Row;
import org.jetbrains.annotations.Nullable;
@@ -93,7 +94,7 @@ public interface SchemaRegistry {
* Resolves batch of binary row against the latest schema.
*
* @param rows Binary rows.
- * @return Schema-aware rows.
+ * @return Schema-aware rows. Contains {@code null} at the same positions
as in {@code rows}.
*/
- Collection<Row> resolve(Collection<BinaryRow> rows);
+ List<Row> resolve(Collection<BinaryRow> rows);
}
diff --git
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/SchemaRegistryImpl.java
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/SchemaRegistryImpl.java
index 75e879cb86..5368222c72 100644
---
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/SchemaRegistryImpl.java
+++
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/registry/SchemaRegistryImpl.java
@@ -148,17 +148,14 @@ public class SchemaRegistryImpl implements SchemaRegistry
{
return resolveInternal(row, schemaDescriptor);
}
- /** {@inheritDoc} */
@Override
- public Collection<Row> resolve(Collection<BinaryRow> binaryRows) {
- final SchemaDescriptor curSchema = waitLatestSchema();
+ public List<Row> resolve(Collection<BinaryRow> binaryRows) {
+ SchemaDescriptor curSchema = waitLatestSchema();
- List<Row> rows = new ArrayList<>(binaryRows.size());
+ var rows = new ArrayList<Row>(binaryRows.size());
- for (BinaryRow r : binaryRows) {
- if (r != null) {
- rows.add(resolveInternal(r, curSchema));
- }
+ for (BinaryRow row : binaryRows) {
+ rows.add(row == null ? null : resolveInternal(row, curSchema));
}
return rows;
diff --git a/modules/table/build.gradle b/modules/table/build.gradle
index 196ff37947..f16310bb56 100644
--- a/modules/table/build.gradle
+++ b/modules/table/build.gradle
@@ -91,6 +91,7 @@ dependencies {
testFixturesImplementation libs.fastutil.core
testFixturesImplementation libs.mockito.core
testFixturesImplementation libs.mockito.junit
+ testFixturesImplementation libs.hamcrest.core
integrationTestImplementation project(':ignite-replicator')
integrationTestImplementation project(':ignite-raft-api')
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
index 3ebf468150..02f7474fe4 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/InternalTable.java
@@ -103,10 +103,12 @@ public interface InternalTable extends ManuallyCloseable {
* Asynchronously get rows from the table.
*
* @param keyRows Rows with key columns set.
- * @param tx The transaction.
- * @return Future representing pending completion of the operation.
+ * @param tx Transaction or {@code null} to auto-commit.
+ * @return Future that will return rows with all columns filled from the
table. The order of collection elements is
+ * guaranteed to be the same as the order of {@code keyRows}. If a
record does not exist, the
+ * element at the corresponding index of the resulting collection is
{@code null}.
*/
- CompletableFuture<Collection<BinaryRow>> getAll(Collection<BinaryRowEx>
keyRows, @Nullable InternalTransaction tx);
+ CompletableFuture<List<BinaryRow>> getAll(Collection<BinaryRowEx> keyRows,
@Nullable InternalTransaction tx);
/**
* Asynchronously get rows from the table for the proposed read timestamp.
@@ -114,9 +116,11 @@ public interface InternalTable extends ManuallyCloseable {
* @param keyRows Rows with key columns set.
* @param readTimestamp Read timestamp.
* @param recipientNode Cluster node that will handle given get request.
- * @return Future representing pending completion of the operation.
+ * @return Future that will return rows with all columns filled from the
table. The order of collection elements is
+ * guaranteed to be the same as the order of {@code keyRows}. If a
record does not exist, the
+ * element at the corresponding index of the resulting collection is
{@code null}.
*/
- CompletableFuture<Collection<BinaryRow>> getAll(
+ CompletableFuture<List<BinaryRow>> getAll(
Collection<BinaryRowEx> keyRows,
HybridTimestamp readTimestamp,
ClusterNode recipientNode
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
index 25ed891f14..bf86b16991 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueBinaryViewImpl.java
@@ -429,7 +429,9 @@ public class KeyValueBinaryViewImpl extends
AbstractTableView implements KeyValu
Map<Tuple, Tuple> pairs = IgniteUtils.newHashMap(rows.size());
for (Row row : schemaReg.resolve(rows)) {
- pairs.put(TableRow.keyTuple(row), TableRow.valueTuple(row));
+ if (row != null) {
+ pairs.put(TableRow.keyTuple(row), TableRow.valueTuple(row));
+ }
}
return pairs;
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
index 76c39a31d5..94db24837e 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/KeyValueViewImpl.java
@@ -529,7 +529,9 @@ public class KeyValueViewImpl<K, V> extends
AbstractTableView implements KeyValu
try {
for (Row row : schemaReg.resolve(rows)) {
- pairs.put(marsh.unmarshalKey(row), marsh.unmarshalValue(row));
+ if (row != null) {
+ pairs.put(marsh.unmarshalKey(row),
marsh.unmarshalValue(row));
+ }
}
return pairs;
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
index 6c34f013fa..b5fc8728bd 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordBinaryViewImpl.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.table;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Flow.Publisher;
@@ -74,18 +75,16 @@ public class RecordBinaryViewImpl extends AbstractTableView
implements RecordVie
return tbl.get(keyRow, (InternalTransaction) tx).thenApply(this::wrap);
}
- /** {@inheritDoc} */
@Override
- public Collection<Tuple> getAll(@Nullable Transaction tx, @NotNull
Collection<Tuple> keyRecs) {
+ public List<Tuple> getAll(@Nullable Transaction tx, Collection<Tuple>
keyRecs) {
return sync(getAllAsync(tx, keyRecs));
}
- /** {@inheritDoc} */
@Override
- public @NotNull CompletableFuture<Collection<Tuple>> getAllAsync(@Nullable
Transaction tx, @NotNull Collection<Tuple> keyRecs) {
+ public CompletableFuture<List<Tuple>> getAllAsync(@Nullable Transaction
tx, Collection<Tuple> keyRecs) {
Objects.requireNonNull(keyRecs);
- return tbl.getAll(mapToBinary(keyRecs, true), (InternalTransaction)
tx).thenApply(this::wrap);
+ return tbl.getAll(mapToBinary(keyRecs, true), (InternalTransaction)
tx).thenApply(binaryRows -> wrap(binaryRows, true));
}
/** {@inheritDoc} */
@@ -161,7 +160,7 @@ public class RecordBinaryViewImpl extends AbstractTableView
implements RecordVie
public @NotNull CompletableFuture<Collection<Tuple>>
insertAllAsync(@Nullable Transaction tx, @NotNull Collection<Tuple> recs) {
Objects.requireNonNull(recs);
- return tbl.insertAll(mapToBinary(recs, false), (InternalTransaction)
tx).thenApply(this::wrap);
+ return tbl.insertAll(mapToBinary(recs, false), (InternalTransaction)
tx).thenApply(rows -> wrap(rows, false));
}
/** {@inheritDoc} */
@@ -273,7 +272,7 @@ public class RecordBinaryViewImpl extends AbstractTableView
implements RecordVie
public @NotNull CompletableFuture<Collection<Tuple>>
deleteAllAsync(@Nullable Transaction tx, @NotNull Collection<Tuple> keyRecs) {
Objects.requireNonNull(keyRecs);
- return tbl.deleteAll(mapToBinary(keyRecs, true), (InternalTransaction)
tx).thenApply(this::wrap);
+ return tbl.deleteAll(mapToBinary(keyRecs, true), (InternalTransaction)
tx).thenApply(rows -> wrap(rows, false));
}
/** {@inheritDoc} */
@@ -287,7 +286,7 @@ public class RecordBinaryViewImpl extends AbstractTableView
implements RecordVie
public @NotNull CompletableFuture<Collection<Tuple>>
deleteAllExactAsync(@Nullable Transaction tx, @NotNull Collection<Tuple> recs) {
Objects.requireNonNull(recs);
- return tbl.deleteAllExact(mapToBinary(recs, false),
(InternalTransaction) tx).thenApply(this::wrap);
+ return tbl.deleteAllExact(mapToBinary(recs, false),
(InternalTransaction) tx).thenApply(rows -> wrap(rows, false));
}
/**
@@ -323,17 +322,20 @@ public class RecordBinaryViewImpl extends
AbstractTableView implements RecordVie
* Returns table rows.
*
* @param rows Binary rows.
+ * @param addNull {@code true} if {@code null} is added for missing rows.
*/
- private Collection<Tuple> wrap(Collection<BinaryRow> rows) {
+ private List<Tuple> wrap(Collection<BinaryRow> rows, boolean addNull) {
if (rows.isEmpty()) {
return Collections.emptyList();
}
- Collection<Tuple> wrapped = new ArrayList<>(rows.size());
+ var wrapped = new ArrayList<Tuple>(rows.size());
for (Row row : schemaReg.resolve(rows)) {
if (row != null) {
wrapped.add(TableRow.tuple(row));
+ } else if (addNull) {
+ wrapped.add(null);
}
}
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
index 7c851a7e09..6222c64e32 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/RecordViewImpl.java
@@ -80,18 +80,16 @@ public class RecordViewImpl<R> extends AbstractTableView
implements RecordView<R
return tbl.get(keyRow, (InternalTransaction)
tx).thenApply(this::unmarshal);
}
- /** {@inheritDoc} */
@Override
- public Collection<R> getAll(@Nullable Transaction tx, @NotNull
Collection<R> keyRecs) {
+ public List<R> getAll(@Nullable Transaction tx, Collection<R> keyRecs) {
return sync(getAllAsync(tx, keyRecs));
}
- /** {@inheritDoc} */
@Override
- public @NotNull CompletableFuture<Collection<R>> getAllAsync(@Nullable
Transaction tx, @NotNull Collection<R> keyRecs) {
+ public CompletableFuture<List<R>> getAllAsync(@Nullable Transaction tx,
Collection<R> keyRecs) {
Objects.requireNonNull(keyRecs);
- return tbl.getAll(marshalKeys(keyRecs), (InternalTransaction)
tx).thenApply(this::unmarshal);
+ return tbl.getAll(marshalKeys(keyRecs), (InternalTransaction)
tx).thenApply(binaryRows -> unmarshal(binaryRows, true));
}
/** {@inheritDoc} */
@@ -161,7 +159,7 @@ public class RecordViewImpl<R> extends AbstractTableView
implements RecordView<R
public @NotNull CompletableFuture<Collection<R>> insertAllAsync(@Nullable
Transaction tx, @NotNull Collection<R> recs) {
Collection<BinaryRowEx> rows = marshal(Objects.requireNonNull(recs));
- return tbl.insertAll(rows, (InternalTransaction)
tx).thenApply(this::unmarshal);
+ return tbl.insertAll(rows, (InternalTransaction)
tx).thenApply(binaryRows -> unmarshal(binaryRows, false));
}
/** {@inheritDoc} */
@@ -260,7 +258,7 @@ public class RecordViewImpl<R> extends AbstractTableView
implements RecordView<R
public @NotNull CompletableFuture<Collection<R>> deleteAllAsync(@Nullable
Transaction tx, @NotNull Collection<R> keyRecs) {
Collection<BinaryRowEx> rows =
marshal(Objects.requireNonNull(keyRecs));
- return tbl.deleteAll(rows, (InternalTransaction)
tx).thenApply(this::unmarshal);
+ return tbl.deleteAll(rows, (InternalTransaction)
tx).thenApply(binaryRows -> unmarshal(binaryRows, false));
}
/** {@inheritDoc} */
@@ -274,7 +272,7 @@ public class RecordViewImpl<R> extends AbstractTableView
implements RecordView<R
public @NotNull CompletableFuture<Collection<R>>
deleteAllExactAsync(@Nullable Transaction tx, @NotNull Collection<R> keyRecs) {
Collection<BinaryRowEx> rows =
marshal(Objects.requireNonNull(keyRecs));
- return tbl.deleteAllExact(rows, (InternalTransaction)
tx).thenApply(this::unmarshal);
+ return tbl.deleteAllExact(rows, (InternalTransaction)
tx).thenApply(binaryRows -> unmarshal(binaryRows, false));
}
/**
@@ -410,20 +408,25 @@ public class RecordViewImpl<R> extends AbstractTableView
implements RecordView<R
* Unmarshal records.
*
* @param rows Row collection.
+ * @param addNull {@code true} if {@code null} is added for missing rows.
* @return Records collection.
*/
- private Collection<R> unmarshal(Collection<BinaryRow> rows) {
+ private List<R> unmarshal(Collection<BinaryRow> rows, boolean addNull) {
if (rows.isEmpty()) {
return Collections.emptyList();
}
RecordMarshaller<R> marsh = marshaller();
- List<R> recs = new ArrayList<>(rows.size());
+ var recs = new ArrayList<R>(rows.size());
try {
for (Row row : schemaReg.resolve(rows)) {
- recs.add(marsh.unmarshal(row));
+ if (row != null) {
+ recs.add(marsh.unmarshal(row));
+ } else if (addNull) {
+ recs.add(null);
+ }
}
return recs;
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
index 06724d110b..98fc9148c4 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
@@ -559,7 +559,7 @@ public class InternalTableImpl implements InternalTable {
/** {@inheritDoc} */
@Override
- public CompletableFuture<Collection<BinaryRow>>
getAll(Collection<BinaryRowEx> keyRows, InternalTransaction tx) {
+ public CompletableFuture<List<BinaryRow>> getAll(Collection<BinaryRowEx>
keyRows, InternalTransaction tx) {
if (tx != null && tx.isReadOnly()) {
BinaryRowEx firstRow = keyRows.iterator().next();
@@ -589,7 +589,7 @@ public class InternalTableImpl implements InternalTable {
/** {@inheritDoc} */
@Override
- public CompletableFuture<Collection<BinaryRow>> getAll(
+ public CompletableFuture<List<BinaryRow>> getAll(
Collection<BinaryRowEx> keyRows,
HybridTimestamp readTimestamp,
ClusterNode recipientNode
@@ -1240,7 +1240,7 @@ public class InternalTableImpl implements InternalTable {
* @param rowBatches Row batches by partition ID.
* @return Future of collecting results.
*/
- static CompletableFuture<Collection<BinaryRow>>
collectMultiRowsResponsesWithRestoreOrder(Collection<RowBatch> rowBatches) {
+ static CompletableFuture<List<BinaryRow>>
collectMultiRowsResponsesWithRestoreOrder(Collection<RowBatch> rowBatches) {
return allResultFutures(rowBatches)
.thenApply(response -> {
var result = new
BinaryRow[RowBatch.getTotalRequestedRowSize(rowBatches)];
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
index f1dbf99ceb..cbf9c65442 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
@@ -18,6 +18,8 @@
package org.apache.ignite.internal.table;
import static
org.apache.ignite.internal.schema.DefaultValueProvider.constantProvider;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -356,9 +358,7 @@ public class RecordBinaryViewOperationsTest {
Tuple.create().set("id", 3L)
));
- assertEquals(2, res.size());
- assertTrue(res.contains(rec1));
- assertTrue(res.contains(rec3));
+ assertThat(res, contains(rec1, null, rec3));
}
@Test
@@ -384,9 +384,7 @@ public class RecordBinaryViewOperationsTest {
Tuple.create().set("id", 3L)
));
- assertEquals(2, res.size());
- assertTrue(res.contains(rec1));
- assertTrue(res.contains(rec3));
+ assertThat(res, contains(rec1, null, rec3));
Tuple upRec1 = Tuple.create().set("id", 1L).set("val", 112L);
Tuple rec2 = Tuple.create().set("id", 2L).set("val", 22L);
@@ -402,11 +400,7 @@ public class RecordBinaryViewOperationsTest {
Tuple.create().set("id", 3L)
));
- assertEquals(3, res.size());
-
- assertTrue(res.contains(upRec1));
- assertTrue(res.contains(rec2));
- assertTrue(res.contains(upRec3));
+ assertThat(res, contains(upRec1, rec2, upRec3));
}
@Test
@@ -532,9 +526,7 @@ public class RecordBinaryViewOperationsTest {
Tuple.create().set("id", 3L)
));
- assertEquals(1, current.size());
-
- assertTrue(current.contains(tuple2));
+ assertThat(current, contains(null, tuple2, null));
}
@Test
@@ -588,9 +580,7 @@ public class RecordBinaryViewOperationsTest {
Tuple.create().set("id", 3L)
));
- assertEquals(1, current.size());
-
- assertTrue(current.contains(tuple3Upsert));
+ assertThat(current, contains(null, null, tuple3Upsert));
}
@Test
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
index 5796c6df44..ba1ccb1e5b 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordViewOperationsTest.java
@@ -29,6 +29,8 @@ import static
org.apache.ignite.internal.schema.NativeTypes.STRING;
import static org.apache.ignite.internal.schema.NativeTypes.datetime;
import static org.apache.ignite.internal.schema.NativeTypes.time;
import static org.apache.ignite.internal.schema.NativeTypes.timestamp;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -282,9 +284,7 @@ public class RecordViewOperationsTest {
Collection<TestObjectWithAllTypes> res = tbl.getAll(null,
List.of(key1, key2, key3));
- assertEquals(2, res.size());
- assertTrue(res.contains(val1));
- assertTrue(res.contains(val3));
+ assertThat(res, contains(val1, null, val3));
}
/**
diff --git
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TxAbstractTest.java
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TxAbstractTest.java
index 28cbc2e04d..32e3185a66 100644
---
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TxAbstractTest.java
+++
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/TxAbstractTest.java
@@ -19,7 +19,10 @@ package org.apache.ignite.internal.table;
import static java.util.concurrent.CompletableFuture.allOf;
import static java.util.concurrent.CompletableFuture.completedFuture;
+import static java.util.stream.Collectors.toList;
import static
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -73,6 +76,7 @@ import org.apache.ignite.tx.IgniteTransactions;
import org.apache.ignite.tx.Transaction;
import org.apache.ignite.tx.TransactionException;
import org.apache.ignite.tx.TransactionOptions;
+import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -763,7 +767,7 @@ public abstract class TxAbstractTest extends
IgniteAbstractTest {
Collection<Tuple> ret = accounts.recordView().getAll(null, keys);
- assertEquals(0, ret.size());
+ assertThat(ret, contains(null, null));
accounts.recordView().upsert(null, makeValue(1, 100.));
accounts.recordView().upsert(null, makeValue(2, 200.));
@@ -1696,15 +1700,11 @@ public abstract class TxAbstractTest extends
IgniteAbstractTest {
* @param rows Rows.
* @param expected Expected values.
*/
- private void validateBalance(Collection<Tuple> rows, double... expected) {
- List<Tuple> rows0 = new ArrayList<>(rows);
-
- assertEquals(expected.length, rows.size());
-
- for (int i = 0; i < expected.length; i++) {
- double v = expected[i];
- assertEquals(v, rows0.get(i).doubleValue("balance"));
- }
+ private static void validateBalance(Collection<Tuple> rows, @Nullable
Double... expected) {
+ assertThat(
+ rows.stream().map(tuple -> tuple == null ? null :
tuple.doubleValue("balance")).collect(toList()),
+ contains(expected)
+ );
}
/**
@@ -1897,7 +1897,7 @@ public abstract class TxAbstractTest extends
IgniteAbstractTest {
Transaction readOnlyTx2 = igniteTransactions.begin(new
TransactionOptions().readOnly(true));
Collection<Tuple> retrievedKeys3 =
accounts.recordView().getAll(readOnlyTx2, List.of(makeKey(1), makeKey(2)));
- validateBalance(retrievedKeys3, 300.);
+ validateBalance(retrievedKeys3, null, 300.);
}
@Test
@@ -1964,7 +1964,7 @@ public abstract class TxAbstractTest extends
IgniteAbstractTest {
} else {
res = accountsRv.getAll(null, List.of(makeKey(1), makeKey(2)));
- assertTrue(CollectionUtils.nullOrEmpty(res));
+ assertThat(res, contains(null, null));
}
}
}
diff --git
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummySchemaManagerImpl.java
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummySchemaManagerImpl.java
index 7e0360802d..b9e919d901 100644
---
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummySchemaManagerImpl.java
+++
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummySchemaManagerImpl.java
@@ -17,9 +17,10 @@
package org.apache.ignite.internal.table.impl;
+import static java.util.stream.Collectors.toList;
+
import java.util.Collection;
-import java.util.Objects;
-import java.util.stream.Collectors;
+import java.util.List;
import org.apache.ignite.internal.schema.BinaryRow;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.SchemaRegistry;
@@ -93,9 +94,8 @@ public class DummySchemaManagerImpl implements SchemaRegistry
{
return new Row(schema, row);
}
- /** {@inheritDoc} */
@Override
- public Collection<Row> resolve(Collection<BinaryRow> rows) {
- return
rows.stream().filter(Objects::nonNull).map(this::resolve).collect(Collectors.toList());
+ public List<Row> resolve(Collection<BinaryRow> rows) {
+ return rows.stream().map(binaryRow -> binaryRow == null ? null :
resolve(binaryRow)).collect(toList());
}
}