[
https://issues.apache.org/jira/browse/IGNITE-17041?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mikhail Petrov updated IGNITE-17041:
------------------------------------
Description:
Let's consider the following situaiton:
The first server node is started with the following cache configuration.
{code:java}
QueryEntity qryEntity = new QueryEntity(String.class, Person.class)
.setTableName("PERSON")
.addQueryField("id", Integer.class.getName(), null);
CacheConfiguration<?, ?> ccfg = new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
.setQueryEntities(Collections.singletonList(qryEntity));
{code}
Then we add the column manually like that:
{code:java}
srv.cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("ALTER TABLE PERSON ADD
data INTEGER")).getAll();
{code}
As a result we get query type descriptor with the following DTO fields ->
table columns:
"id" -> "ID"
"DATA" -> "DATA"
(Note that isSqlEscapeAll flag is disabled in the cache configuraiton so the
Ignite automatically creates upper-case aliases for preconfigured entities)
Then lets start second server node with the following cache confiuration:
{code:java}
QueryEntity qryEntity = new QueryEntity(String.class, Person.class)
.setTableName("PERSON")
.addQueryField("id", Integer.class.getName(), null)
.addQueryField("data", Boolean.class.getName(), null);
CacheConfiguration<?, ?> ccfg = new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
.setQueryEntities(Collections.singletonList(qryEntity));
{code}
Note the type of "data" query field is Boolean now
During the join process of the second node first node validates that cache
query fields that configured on the second node is identical with the local
one. If there are unique fields that are not present in the first node's config
then configurations from both nodes are merged to complement each other. If
there are some conflicts (e.g. query fields with identical names has diferent
types) joining node will be rejected.
In the described above example second node joins the cluster with no conflicts.
And merge process completes succcessflully.
As a result we get query type descriptor with the following DTO fields ->
table columns:
"id" -> "ID"
"DATA" -> "DATA" of type Integer
"data" -> "data" of type Boolean
It happens because
1. During merge conflict resolving process we compare only types of the DTO
fields with the same name.
So "DATA" and "data" is considered different fields and no conflicts are
detected.
2. Then we update the cache query configuration on the cluster nodes with the
"data" field that is received from the joining node. But we do not update
corresponding aliases. As a result we crete TABLE column with the same name as
DTO field - "data" in lower case.
Since isSqlEscapeAll flag is disabled for both configuration it's confusing
behaviour.
The expected behaviour is that the second node would be rejected because of
data column type mistmatch.
Currently we useonly query field names to detect conflicts during merge process
( see org.apache.ignite.cache.QueryEntity#checkFields method). It seeems that
we sould consider query fields aliases as well.
was:
Let's consider the following situaiton:
The first server node is started with the following cache configuration.
{code:java}
QueryEntity qryEntity = new QueryEntity(String.class, Person.class)
.setTableName("PERSON")
.addQueryField("id", Integer.class.getName(), null);
CacheConfiguration<?, ?> ccfg = new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
.setQueryEntities(Collections.singletonList(qryEntity));
{code}
Then we add the column manually like that:
{code:java}
srv.cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("ALTER TABLE PERSON ADD
data INTEGER")).getAll();
{code}
As a result we get query entity with the following fields -> aliases:
"id" -> "ID" (Note that isSqlEscapeAll flag is disabled in the cache
configuraiton so the Ignite automatically creates upper-case aliases for
preconfigured entities)
"DATA" -> "DATA"
Then lets start second server node with the following cache confiuration:
{code:java}
QueryEntity qryEntity = new QueryEntity(String.class, Person.class)
.setTableName("PERSON")
.addQueryField("id", Integer.class.getName(), null)
.addQueryField("data", Boolean.class.getName(), null);
CacheConfiguration<?, ?> ccfg = new
CacheConfiguration<>(DEFAULT_CACHE_NAME)
.setQueryEntities(Collections.singletonList(qryEntity));
{code}
Note the type of "data" query field is Boolean now.
The mentioned above configuration will be processed as query entity with the
follwing fields -> aliases:
"id" -> "ID"
"data" -> "DATA"
Note that isSqlEscapeAll flag is disabled in the cache configuraiton so the
Ignite automatically creates upper-case aliases for preconfigured entities and
uses them as column names.
During the join process of the second node first node validates that cache
query fields configuration which configured on the second node is identical
with the local one. If there are unique fields that are not present in the
first node's config then configurations from both nodes are merged to
complement each other. If there are some conflicts (e.g. the same field has
diferent types for joining and "in cluster" nodes) joining node will be
rejected.
In the described above example second node joins the cluster with no conflicts.
Merge process completes succcessflully and we get two data columns - "data" and
"DATA".
Since isSqlEscapeAll flag is disabled for both configuration it's confusing
behaviour.
The expected behaviour is that the second node would be rejected.
Currently we use only only query field names to detect conflicts during merge
process ( see org.apache.ignite.cache.QueryEntity#checkFields method. It seeems
that we sould consider query fields aliases as well.
> Query fields merge process does not consider aliases to determine conflicts.
> ----------------------------------------------------------------------------
>
> Key: IGNITE-17041
> URL: https://issues.apache.org/jira/browse/IGNITE-17041
> Project: Ignite
> Issue Type: Bug
> Reporter: Mikhail Petrov
> Assignee: Mikhail Petrov
> Priority: Major
> Labels: ise
> Time Spent: 10m
> Remaining Estimate: 0h
>
> Let's consider the following situaiton:
> The first server node is started with the following cache configuration.
> {code:java}
> QueryEntity qryEntity = new QueryEntity(String.class, Person.class)
> .setTableName("PERSON")
> .addQueryField("id", Integer.class.getName(), null);
> CacheConfiguration<?, ?> ccfg = new
> CacheConfiguration<>(DEFAULT_CACHE_NAME)
> .setQueryEntities(Collections.singletonList(qryEntity));
> {code}
> Then we add the column manually like that:
> {code:java}
> srv.cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("ALTER TABLE PERSON
> ADD data INTEGER")).getAll();
> {code}
> As a result we get query type descriptor with the following DTO fields ->
> table columns:
> "id" -> "ID"
> "DATA" -> "DATA"
> (Note that isSqlEscapeAll flag is disabled in the cache configuraiton so the
> Ignite automatically creates upper-case aliases for preconfigured entities)
> Then lets start second server node with the following cache confiuration:
> {code:java}
> QueryEntity qryEntity = new QueryEntity(String.class, Person.class)
> .setTableName("PERSON")
> .addQueryField("id", Integer.class.getName(), null)
> .addQueryField("data", Boolean.class.getName(), null);
> CacheConfiguration<?, ?> ccfg = new
> CacheConfiguration<>(DEFAULT_CACHE_NAME)
> .setQueryEntities(Collections.singletonList(qryEntity));
> {code}
> Note the type of "data" query field is Boolean now
> During the join process of the second node first node validates that cache
> query fields that configured on the second node is identical with the local
> one. If there are unique fields that are not present in the first node's
> config then configurations from both nodes are merged to complement each
> other. If there are some conflicts (e.g. query fields with identical names
> has diferent types) joining node will be rejected.
> In the described above example second node joins the cluster with no
> conflicts.
> And merge process completes succcessflully.
> As a result we get query type descriptor with the following DTO fields ->
> table columns:
> "id" -> "ID"
> "DATA" -> "DATA" of type Integer
> "data" -> "data" of type Boolean
> It happens because
> 1. During merge conflict resolving process we compare only types of the DTO
> fields with the same name.
> So "DATA" and "data" is considered different fields and no conflicts are
> detected.
> 2. Then we update the cache query configuration on the cluster nodes with
> the "data" field that is received from the joining node. But we do not update
> corresponding aliases. As a result we crete TABLE column with the same name
> as DTO field - "data" in lower case.
> Since isSqlEscapeAll flag is disabled for both configuration it's confusing
> behaviour.
> The expected behaviour is that the second node would be rejected because of
> data column type mistmatch.
> Currently we useonly query field names to detect conflicts during merge
> process ( see org.apache.ignite.cache.QueryEntity#checkFields method). It
> seeems that we sould consider query fields aliases as well.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)