[
https://issues.apache.org/jira/browse/IGNITE-21296?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17815236#comment-17815236
]
Roman Puchkovskiy commented on IGNITE-21296:
--------------------------------------------
In PartitionReplicaListener, we don't account for the possible change of the
table schema when comparing tuples. For key tuples (and key parts of the full
tuples) it's ok as definitions of key columns in the schema cannot change. But
some commands (at least, DELETE_EXACT, DELETE_EXACT_ALL and REPLACE) look at
the 'value' part of a tuple when deciding on the following logic (delete or
not, replace or not), and the same 'value' part might look differently if
marshalled using different schemas, so a naive comparison might give a false
'not equals' result.
The following test demonstrates the problem:
@Test
void test() {
IgniteImpl node = cluster.node(0);
try (Session session = node.sql().createSession()) {
session.execute(null, "CREATE TABLE test(id int primary key)");
}
KeyValueView<Tuple, Tuple> view = node.tables().table("test").keyValueView();
Tuple key = Tuple.create().set("id", 1);
view.put(null, key, Tuple.create());
try (Session session = node.sql().createSession()) {
session.execute(null, "ALTER TABLE test add column added int");
}
boolean removed = view.remove(null, key, Tuple.create());
assertTrue(removed);
}
We can fix this if we coerce both tuples (the search one and the one from the
storage) to the same version. The coercion must be done to the version of the
request (in this case, it will always be from version V1 to V2, where V1<=V2;
we always support such conversions, but not the other way around).
> Altering the table causes the KV API to break
> ---------------------------------------------
>
> Key: IGNITE-21296
> URL: https://issues.apache.org/jira/browse/IGNITE-21296
> Project: Ignite
> Issue Type: Bug
> Reporter: Ivan Gagarkin
> Priority: Critical
> Labels: ignite-3
> Attachments: alterTableTest1.java
>
>
>
> *Steps to Reproduce:*
> # Create a table using the command: {{{}CREATE TABLE TEST (id INT PRIMARY
> KEY, country VARCHAR){}}}.
> # Create a POJO with corresponding fields to the table.
> # Create a Key-Value (KV) view: {{{}KeyValueView<Integer, Country>
> countryValueView = table.keyValueView(Mapper.of(Integer.class),
> Mapper.of(Country.class));{}}}.
> # Insert some data into the table.
> # Alter the table by adding a new column: {{{}ALTER TABLE TEST ADD COLUMN
> city VARCHAR{}}}.
> # Create a new POJO to accommodate the added column.
> # Create a new KV view: {{{}KeyValueView<Integer, CountryCity>
> countryCityKeyValueView =
> CLUSTER.node(0).tables().table(TABLE_NAME).keyValueView(Mapper.of(Integer.class),
> Mapper.of(CountryCity.class));{}}}.
> # Attempt to remove data from the table using the first KV view:
> {{{}assertTrue(countryValueView.remove(null, 0, valuePojo));{}}}. This fails
> with the error "No mapped object field found for column 'CITY'".
> # Try to remove data using the second KV view:
> {{{}assertTrue(countryCityKeyValueView.remove(null, 0, new
> CountryCity(valuePojo.country(), null)));{}}}. This returns {{{}false{}}}.
> *Expected Behavior:*
> It should be possible to remove values using either of the KV views after
> altering the table structure.
> *Actual Behavior:*
> * Unable to remove values using the first KV view due to the lack of a
> 'city' column in the original POJO.
> * Unable to remove values using the second KV view as the {{equals}} method
> does not function as expected.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)