[ 
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: the second node would be rejected because of column 
type mistmatch.

  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 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: the second node would be rejected because of 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.


> 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: the second node would be rejected because of column 
> type mistmatch.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to