This is an automated email from the ASF dual-hosted git repository.
shishkovilja pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new bc1e3d277e3 IGNITE-28767 Use Message DTO to transfer QueryEntity
(#13236)
bc1e3d277e3 is described below
commit bc1e3d277e33d83b4df5511203c74a4f33b9743f
Author: Ilya Shishkov <[email protected]>
AuthorDate: Tue Jul 7 12:27:00 2026 +0300
IGNITE-28767 Use Message DTO to transfer QueryEntity (#13236)
---
.../ignite/internal/CoreMessagesProvider.java | 8 +-
.../internal/cache/query/QueryIndexMessage.java | 6 +-
.../internal/processors/query/QueryField.java | 6 +-
.../query/schema/message/QueryEntityExMessage.java | 88 ++++++++++
.../query/schema/message/QueryEntityMessage.java | 158 +++++++++++++++++
.../schema/operation/SchemaAbstractOperation.java | 6 +-
.../operation/SchemaAddQueryEntityOperation.java | 65 +++----
.../SchemaAlterTableAddColumnOperation.java | 3 -
.../SchemaAlterTableDropColumnOperation.java | 3 -
.../operation/SchemaIndexCreateOperation.java | 3 -
.../schema/operation/SchemaIndexDropOperation.java | 3 -
.../QueryEntityMessageSerializationTest.java | 193 +++++++++++++++++++++
.../testsuites/IgniteCacheQuerySelfTestSuite6.java | 2 +
13 files changed, 476 insertions(+), 68 deletions(-)
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
index e037bd50f02..fb71225adb0 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/CoreMessagesProvider.java
@@ -218,6 +218,8 @@ import
org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQuery
import
org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageResponse;
import
org.apache.ignite.internal.processors.query.messages.GridQueryKillRequest;
import
org.apache.ignite.internal.processors.query.messages.GridQueryKillResponse;
+import
org.apache.ignite.internal.processors.query.schema.message.QueryEntityExMessage;
+import
org.apache.ignite.internal.processors.query.schema.message.QueryEntityMessage;
import
org.apache.ignite.internal.processors.query.schema.message.QueryInlineSizesDataBagItem;
import
org.apache.ignite.internal.processors.query.schema.message.QueryProposalsDataBagItem;
import
org.apache.ignite.internal.processors.query.schema.message.SchemaFinishDiscoveryMessage;
@@ -589,7 +591,9 @@ public class CoreMessagesProvider extends
AbstractMarshallableMessageFactoryProv
withNoSchema(GridDhtTxSalvageMessage.class);
withSchema(CacheContinuousQueryEntry.class);
withNoSchema(QueryInlineSizesDataBagItem.class);
- withSchema(QueryProposalsDataBagItem.class);
+ withNoSchema(QueryProposalsDataBagItem.class);
+ withNoSchema(QueryEntityMessage.class);
+ withNoSchema(QueryEntityExMessage.class);
// [11200 - 11300]: Compute, distributed process messages.
msgIdx = 11200;
@@ -644,7 +648,7 @@ public class CoreMessagesProvider extends
AbstractMarshallableMessageFactoryProv
withNoSchema(UserAuthenticateRequestMessage.class);
withNoSchema(UserAuthenticateResponseMessage.class);
withNoSchema(TcpDiscoveryAuthFailedMessage.class);
- withSchema(AuthentificationDataBagItem.class);
+ withNoSchema(AuthentificationDataBagItem.class);
// [12200 - 12300]: Binary, classloading and marshalling messages.
msgIdx = 12200;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/QueryIndexMessage.java
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/QueryIndexMessage.java
index c42415be029..1bdb38fc3f0 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/QueryIndexMessage.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/QueryIndexMessage.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.cache.query;
-import java.io.Serializable;
import java.util.LinkedHashMap;
import org.apache.ignite.cache.QueryIndex;
import org.apache.ignite.cache.QueryIndexType;
@@ -28,10 +27,7 @@ import
org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
/** Message for {@link QueryIndex}. */
-public class QueryIndexMessage implements Serializable, Message {
- /** */
- private static final long serialVersionUID = 0L;
-
+public class QueryIndexMessage implements Message {
/** Index name. */
@Order(0)
public String name;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
index b24e523a2b7..29659e60da3 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryField.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.processors.query;
-import java.io.Serializable;
import org.apache.ignite.internal.Order;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.plugin.extensions.communication.Message;
@@ -25,10 +24,7 @@ import
org.apache.ignite.plugin.extensions.communication.Message;
/**
* Query field metadata.
*/
-public class QueryField implements Serializable, Message {
- /** */
- private static final long serialVersionUID = 0L;
-
+public class QueryField implements Message {
/** Field name. */
@Order(0)
String name;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityExMessage.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityExMessage.java
new file mode 100644
index 00000000000..e080910dd81
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityExMessage.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.schema.message;
+
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.internal.Order;
+import org.apache.ignite.internal.processors.query.QueryEntityEx;
+
+/** Message for {@link QueryEntityEx} transfer. */
+public class QueryEntityExMessage extends QueryEntityMessage {
+ /** Whether to preserve order specified by 'keyFields' or not. */
+ @Order(0)
+ boolean preserveKeysOrder;
+
+ /** Whether a primary key should be autocreated or not. */
+ @Order(1)
+ boolean implicitPk;
+
+ /** Whether absent PK parts should be filled with defaults or not. */
+ @Order(2)
+ boolean fillAbsentPKsWithDefaults;
+
+ /** INLINE_SIZE for PK index. */
+ @Order(3)
+ int pkInlineSize;
+
+ /** INLINE_SIZE for affinity field index. */
+ @Order(4)
+ int affKeyInlineSize;
+
+ /** Whether query entity was created by SQL. */
+ @Order(5)
+ boolean sql;
+
+ /** */
+ public QueryEntityExMessage() { }
+
+ /**
+ * @param qryEntity Original {@link QueryEntity}.
+ */
+ public QueryEntityExMessage(QueryEntityEx qryEntity) {
+ super(qryEntity);
+
+ preserveKeysOrder = qryEntity.isPreserveKeysOrder();
+ implicitPk = qryEntity.implicitPk();
+ fillAbsentPKsWithDefaults = qryEntity.fillAbsentPKsWithDefaults();
+
+ pkInlineSize = qryEntity.getPrimaryKeyInlineSize() != null ?
qryEntity.getPrimaryKeyInlineSize() : -1;
+
+ affKeyInlineSize = qryEntity.getAffinityKeyInlineSize() != null ?
qryEntity.getAffinityKeyInlineSize() : -1;
+
+ sql = qryEntity.sql();
+ }
+
+ /** {@inheritDoc} */
+ @Override public QueryEntity toEntity() {
+ QueryEntityEx qryEntity = new QueryEntityEx(entityBase());
+
+ qryEntity.setNotNullFields(notNullFields);
+ qryEntity.setPreserveKeysOrder(preserveKeysOrder);
+ qryEntity.implicitPk(implicitPk);
+ qryEntity.fillAbsentPKsWithDefaults(fillAbsentPKsWithDefaults);
+ qryEntity.sql(sql);
+
+ if (pkInlineSize != -1)
+ qryEntity.setPrimaryKeyInlineSize(pkInlineSize);
+
+ if (affKeyInlineSize != -1)
+ qryEntity.setAffinityKeyInlineSize(affKeyInlineSize);
+
+ return qryEntity;
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
new file mode 100644
index 00000000000..8c6daf46cfd
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.schema.message;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.internal.MarshallableMessage;
+import org.apache.ignite.internal.Order;
+import org.apache.ignite.internal.cache.query.QueryIndexMessage;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.marshaller.Marshaller;
+
+/**
+ * Message for {@link QueryEntity} transfer.
+ */
+public class QueryEntityMessage implements MarshallableMessage {
+ /** Key type. */
+ @Order(0)
+ String keyType;
+
+ /** Value type. */
+ @Order(1)
+ String valType;
+
+ /** Key name. */
+ @Order(2)
+ String keyFieldName;
+
+ /** Value name. */
+ @Order(3)
+ String valFieldName;
+
+ /** Fields available for query. */
+ @Order(4)
+ LinkedHashMap<String, String> fields;
+
+ /** Set of field names that belong to the key. */
+ @Order(5)
+ String[] keyFields;
+
+ /** Aliases. */
+ @Order(6)
+ Map<String, String> aliases;
+
+ /** Collection of query indexes. */
+ @Order(7)
+ Collection<QueryIndexMessage> idxs;
+
+ /** Table name. */
+ @Order(8)
+ String tableName;
+
+ /**
+ * Fields that must have non-null value.
+ * NB: Used in serde of both QueryEntity and QueryEntityEx in order to
avoid duplication.
+ */
+ @Order(9)
+ Set<String> notNullFields;
+
+ /** Fields default values. */
+ Map<String, Object> dfltFieldValues;
+
+ /** Serialized form of {@link #dfltFieldValues}. */
+ @Order(10)
+ byte[] dfltFieldValuesBytes;
+
+ /** Precision(Maximum length) for fields. */
+ @Order(11)
+ Map<String, Integer> fieldsPrecision;
+
+ /** Scale for fields. */
+ @Order(12)
+ Map<String, Integer> fieldsScale;
+
+ /** */
+ public QueryEntityMessage() { }
+
+ /** @param qryEntity Original {@link QueryEntity}. */
+ public QueryEntityMessage(QueryEntity qryEntity) {
+ keyType = qryEntity.getKeyType();
+ valType = qryEntity.getValueType();
+
+ keyFieldName = qryEntity.getKeyFieldName();
+ valFieldName = qryEntity.getValueFieldName();
+
+ fields = qryEntity.getFields();
+ aliases = qryEntity.getAliases();
+
+ if (!F.isEmpty(qryEntity.getKeyFields()))
+ keyFields = qryEntity.getKeyFields().toArray(U.EMPTY_STRS);
+
+ if (!F.isEmpty(qryEntity.getIndexes()))
+ idxs = F.viewReadOnly(qryEntity.getIndexes(),
QueryIndexMessage::new);
+
+ tableName = qryEntity.getTableName();
+
+ notNullFields = qryEntity.getNotNullFields();
+ dfltFieldValues = qryEntity.getDefaultFieldValues();
+ fieldsPrecision = qryEntity.getFieldsPrecision();
+ fieldsScale = qryEntity.getFieldsScale();
+ }
+
+ /** @return Original {@link QueryEntity}. */
+ public QueryEntity toEntity() {
+ return entityBase().setNotNullFields(notNullFields);
+ }
+
+ /** @return Entity without 'notNullFields.' */
+ protected QueryEntity entityBase() {
+ return new QueryEntity()
+ .setKeyType(keyType)
+ .setValueType(valType)
+ .setKeyFieldName(keyFieldName)
+ .setValueFieldName(valFieldName)
+ .setFields(fields)
+ .setKeyFields(!F.isEmpty(keyFields) ? new
LinkedHashSet<>(List.of(keyFields)) : null)
+ .setAliases(aliases)
+ .setIndexes(!F.isEmpty(idxs) ? F.transform(idxs,
QueryIndexMessage::queryIndex) : null)
+ .setTableName(tableName)
+ .setDefaultFieldValues(dfltFieldValues)
+ .setFieldsPrecision(fieldsPrecision)
+ .setFieldsScale(fieldsScale);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void prepareMarshal(Marshaller marsh) throws
IgniteCheckedException {
+ if (!F.isEmpty(dfltFieldValues))
+ dfltFieldValuesBytes = U.marshal(marsh, dfltFieldValues);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void finishUnmarshal(Marshaller marsh, ClassLoader
clsLdr) throws IgniteCheckedException {
+ if (!F.isEmpty(dfltFieldValuesBytes))
+ dfltFieldValues = U.unmarshal(marsh, dfltFieldValuesBytes, clsLdr);
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAbstractOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAbstractOperation.java
index 5264fbe2c6a..c3a83e31888 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAbstractOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAbstractOperation.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.processors.query.schema.operation;
-import java.io.Serializable;
import java.util.UUID;
import org.apache.ignite.internal.Order;
import org.apache.ignite.internal.util.typedef.internal.S;
@@ -26,10 +25,7 @@ import
org.apache.ignite.plugin.extensions.communication.Message;
/**
* Abstract operation on schema.
*/
-public abstract class SchemaAbstractOperation implements Serializable, Message
{
- /** */
- private static final long serialVersionUID = 0L;
-
+public abstract class SchemaAbstractOperation implements Message {
/** Operation ID. */
@Order(0)
UUID opId;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
index ebb23aff57e..3d700460bb7 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
@@ -19,27 +19,22 @@ package
org.apache.ignite.internal.processors.query.schema.operation;
import java.util.Collection;
import java.util.UUID;
-import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.internal.MarshallableMessage;
import org.apache.ignite.internal.Order;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.Marshaller;
-
-/**
- * Enabling indexing on cache operation.
- */
-public class SchemaAddQueryEntityOperation extends SchemaAbstractOperation
implements MarshallableMessage {
- /** */
- private static final long serialVersionUID = 0L;
+import org.apache.ignite.internal.processors.query.QueryEntityEx;
+import
org.apache.ignite.internal.processors.query.schema.message.QueryEntityExMessage;
+import
org.apache.ignite.internal.processors.query.schema.message.QueryEntityMessage;
+import org.apache.ignite.internal.util.typedef.F;
+
+/** Operation, which enables indexing on cache operation. */
+public class SchemaAddQueryEntityOperation extends SchemaAbstractOperation {
+ /** Query entities messages. */
+ @Order(0)
+ Collection<QueryEntityMessage> entitiesMsgs;
- /** */
+ /** Original query entities. We keep them to avoid unneccessary
conversions from messages. */
private Collection<QueryEntity> entities;
- /** Serialized form of query entities. */
- @Order(0)
- transient byte[] qryEntitiesBytes;
-
/** */
@Order(1)
int qryParallelism;
@@ -71,42 +66,34 @@ public class SchemaAddQueryEntityOperation extends
SchemaAbstractOperation imple
this.entities = entities;
this.qryParallelism = qryParallelism;
this.sqlEscape = sqlEscape;
+
+ entitiesMsgs = F.viewReadOnly(entities, this::makeEntityMessage);
}
- /**
- * @return Collection of query entities.
- */
+ /** @return Collection of query entities. */
public Collection<QueryEntity> entities() {
+ if (entities == null)
+ entities = F.transform(entitiesMsgs, QueryEntityMessage::toEntity);
+
return entities;
}
- /**
- * @return Query parallelism.
- */
+ /** @return Query parallelism. */
public int queryParallelism() {
return qryParallelism;
}
- /**
- * @return Sql escape flag.
- */
+ /** @return Sql escape flag. */
public boolean isSqlEscape() {
return sqlEscape;
}
- /** {@inheritDoc} */
- @Override public void prepareMarshal(Marshaller marsh) throws
IgniteCheckedException {
- if (entities != null)
- qryEntitiesBytes = U.marshal(marsh, entities);
- }
-
- /** {@inheritDoc} */
- @Override public void finishUnmarshal(Marshaller marsh, ClassLoader
clsLdr) throws IgniteCheckedException {
- if (qryEntitiesBytes != null) {
- entities = U.unmarshal(marsh, qryEntitiesBytes, clsLdr);
-
- qryEntitiesBytes = null;
- }
+ /**
+ * @param qryEntity Query entity.
+ * @return The appropriate query entity message.
+ */
+ private QueryEntityMessage makeEntityMessage(QueryEntity qryEntity) {
+ return qryEntity instanceof QueryEntityEx ? new
QueryEntityExMessage((QueryEntityEx)qryEntity)
+ : new QueryEntityMessage(qryEntity);
}
-
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableAddColumnOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableAddColumnOperation.java
index 11d77d31c5b..481e8f26fdd 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableAddColumnOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableAddColumnOperation.java
@@ -27,9 +27,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
* Schema index drop operation.
*/
public class SchemaAlterTableAddColumnOperation extends
SchemaAbstractOperation {
- /** */
- private static final long serialVersionUID = 0L;
-
/** Target table name. */
@Order(0)
String tblName;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableDropColumnOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableDropColumnOperation.java
index cf48709e921..1aca33c5717 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableDropColumnOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAlterTableDropColumnOperation.java
@@ -26,9 +26,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
* Schema alter table drop column operation.
*/
public class SchemaAlterTableDropColumnOperation extends
SchemaAbstractOperation {
- /** */
- private static final long serialVersionUID = 0L;
-
/** Target table name. */
@Order(0)
String tblName;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexCreateOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexCreateOperation.java
index 056ccaae028..7dcde0c297e 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexCreateOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexCreateOperation.java
@@ -29,9 +29,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
* Schema index create operation.
*/
public class SchemaIndexCreateOperation extends SchemaIndexAbstractOperation {
- /** */
- private static final long serialVersionUID = 0L;
-
/** Table name. */
@Order(0)
String tblName;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexDropOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexDropOperation.java
index 6962fbb0ee5..4d0db89a638 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexDropOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaIndexDropOperation.java
@@ -25,9 +25,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
* Schema index drop operation.
*/
public class SchemaIndexDropOperation extends SchemaIndexAbstractOperation {
- /** */
- private static final long serialVersionUID = 0L;
-
/** Index name. */
@Order(0)
String idxName;
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
new file mode 100644
index 00000000000..6ed6171d81a
--- /dev/null
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.schema.message;
+
+import java.io.Externalizable;
+import java.io.Serializable;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.CoreMessagesProvider;
+import org.apache.ignite.internal.direct.DirectMessageReader;
+import org.apache.ignite.internal.direct.DirectMessageWriter;
+import
org.apache.ignite.internal.managers.communication.IgniteMessageFactoryImpl;
+import org.apache.ignite.internal.processors.query.QueryEntityEx;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageFactory;
+import
org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider;
+import org.apache.ignite.plugin.extensions.communication.MessageSerializer;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static org.apache.ignite.marshaller.Marshallers.jdk;
+import static
org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi.makeMessageType;
+
+/** Test for serialization round-trip of {@link QueryEntityMessage} and {@link
QueryEntityExMessage}. */
+public class QueryEntityMessageSerializationTest extends
GridCommonAbstractTest {
+ /** Error suffix. */
+ public static final String ERROR_SUFFIX = " count is not equal to the
expected fields count. " +
+ "Has the number of fields in the `QueryEntity` or `QueryEntityEx`
classes changed?";
+
+ /** */
+ private final Marshaller marsh = jdk();
+
+ /** */
+ private final MessageFactory msgFactory = new IgniteMessageFactoryImpl(
+ new MessageFactoryProvider[] {new CoreMessagesProvider(marsh, marsh,
U.gridClassLoader())});
+
+ /** */
+ @Test
+ public void testQueryEntity() throws Exception {
+ QueryEntity entity = queryEntity();
+
+ assertEquals(entity, serializeAndDeserialize(entity,
serializableFieldsCount(QueryEntity.class)));
+ }
+
+ /** */
+ @Test
+ public void testQueryEntityEx() throws Exception {
+ QueryEntityEx entity = queryEntityEx();
+
+ long expReadWriteCnt = serializableFieldsCount(QueryEntityEx.class) -
+ /* QueryEntityEx duplicates 'notNullFields', but
'QueryEntityExMessage' doesn't */ 1;
+
+ QueryEntity res = serializeAndDeserialize(entity, expReadWriteCnt);
+
+ assertTrue(res instanceof QueryEntityEx);
+ assertEquals(entity, res);
+
+ // Not part of QueryEntityEx.equals(), so assert it explicitly.
+ assertEquals(entity.fillAbsentPKsWithDefaults(),
((QueryEntityEx)res).fillAbsentPKsWithDefaults());
+ }
+
+ /**
+ * @param src Source entity.
+ * @param expReadsWritesCnt Expected count of field reads and writes.
+ *
+ * @return Entity read during a full serde round-trip.
+ */
+ private QueryEntity serializeAndDeserialize(QueryEntity src, long
expReadsWritesCnt) {
+ QueryEntityMessage msg = src instanceof QueryEntityEx
+ ? new QueryEntityExMessage((QueryEntityEx)src) : new
QueryEntityMessage(src);
+
+ return writeAndReadBack(msg, expReadsWritesCnt).toEntity();
+ }
+
+ /**
+ * @param cls Class of an object.
+ */
+ private long serializableFieldsCount(Class<?> cls) {
+ if (cls == Object.class)
+ return 0;
+
+ assertTrue("Not a serializable class: " + cls,
Serializable.class.isAssignableFrom(cls));
+ assertFalse("Should not be Externalizable:" + cls,
Externalizable.class.isAssignableFrom(cls));
+
+ return serializableFieldsCount(cls.getSuperclass()) +
Arrays.stream(cls.getDeclaredFields())
+ .filter(f -> !Modifier.isStatic(f.getModifiers()) &&
!Modifier.isTransient(f.getModifiers()))
+ .count();
+ }
+
+ /**
+ * @param msg Message to write and read back through {@link
DirectMessageWriter}/{@link DirectMessageReader}.
+ * @param expReadsWritesCnt Expected count of field reads and writes.
+ * @param <T> Type of Message.
+ *
+ * @return Restored message.
+ */
+ private <T extends Message> T writeAndReadBack(T msg, long
expReadsWritesCnt) {
+ ByteBuffer buf = ByteBuffer.allocate(64 * 1024);
+
+ MessageSerializer<T> serde =
(MessageSerializer<T>)msgFactory.serializer(msg.directType());
+
+ DirectMessageWriter writer = new DirectMessageWriter(msgFactory);
+ writer.setBuffer(buf);
+
+ assertTrue(serde.writeTo(msg, writer));
+ assertEquals("Writes" + ERROR_SUFFIX,
+ expReadsWritesCnt, writer.state());
+
+ buf.flip();
+
+ DirectMessageReader reader = new DirectMessageReader(msgFactory, null);
+ reader.setBuffer(buf);
+
+ T res = (T)msgFactory.create(makeMessageType(buf.get(), buf.get()));
+
+ assertTrue(serde.readFrom(res, reader));
+ assertEquals("Reads" + ERROR_SUFFIX,
+ expReadsWritesCnt, reader.state());
+
+ return res;
+ }
+
+ /** @return Query entity with every field populated, including non-empty
default field values. */
+ private QueryEntity queryEntity() {
+ LinkedHashMap<String, String> fields = new LinkedHashMap<>();
+ fields.put("id", Integer.class.getName());
+ fields.put("name", String.class.getName());
+ fields.put("price", BigDecimal.class.getName());
+
+ return new QueryEntity()
+ .setKeyType(Integer.class.getName())
+ .setValueType("org.apache.ignite.Person")
+ .setKeyFieldName("id")
+ .setValueFieldName("name")
+ .setTableName("PERSON")
+ .setFields(fields)
+ .setKeyFields(Set.of("id"))
+ .setAliases(Map.of("name", "NAME_ALIAS"))
+ .setIndexes(List.of(new QueryIndex("name",
QueryIndexType.SORTED).setInlineSize(32)))
+ .setNotNullFields(Set.of("id", "name"))
+ .setDefaultFieldValues(Map.of(
+ "name", "unknown",
+ "price", new BigDecimal("9.99"),
+ "id", 42))
+ .setFieldsPrecision(Map.of("name", 64))
+ .setFieldsScale(Map.of("price", 2));
+ }
+
+ /** @return Extended query entity with all base and extended fields
populated. */
+ private QueryEntityEx queryEntityEx() {
+ QueryEntity base = queryEntity();
+ base.setNotNullFields(null);
+
+ QueryEntityEx entity = new QueryEntityEx(base);
+
+ // Natural QueryEntityEx: notNullFields lives only in the Ex field,
base shadow stays null.
+ entity.setNotNullFields(Set.of("id", "name"));
+ entity.setPreserveKeysOrder(true);
+ entity.implicitPk(true);
+ entity.fillAbsentPKsWithDefaults(true);
+ entity.sql(true);
+ entity.setPrimaryKeyInlineSize(16);
+ entity.setAffinityKeyInlineSize(24);
+
+ return entity;
+ }
+}
diff --git
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite6.java
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite6.java
index 81047163d75..60d7e9954dd 100644
---
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite6.java
+++
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite6.java
@@ -49,6 +49,7 @@ import
org.apache.ignite.internal.processors.query.IgniteInsertNullableDuplicate
import
org.apache.ignite.internal.processors.query.IgniteSqlSinglePartitionMultiParallelismTest;
import
org.apache.ignite.internal.processors.query.MemLeakOnSqlWithClientReconnectTest;
import org.apache.ignite.internal.processors.query.QueryEntityAliasesTest;
+import
org.apache.ignite.internal.processors.query.schema.message.QueryEntityMessageSerializationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -90,6 +91,7 @@ import org.junit.runners.Suite;
DropTableAfterCteSqlQueryTest.class,
LocalContinuousQueryWithNodeFailureTest.class,
ContinuousQueryUserCodeExceptionTest.class,
+ QueryEntityMessageSerializationTest.class,
})
public class IgniteCacheQuerySelfTestSuite6 {
}