[ 
https://issues.apache.org/jira/browse/IGNITE-28907?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Oleg Valuyskiy updated IGNITE-28907:
------------------------------------
    Description: 
h2. Problem

Apache Ignite allows the same SQL value type to be configured simultaneously 
through:
 * {*}CacheConfiguration#setIndexedTypes{*}, which creates a *QueryEntity* from 
annotations such as *@QuerySqlField*
 * {*}CacheConfiguration#setQueryEntities{*}, which supplies a *QueryEntity* 
explicitly configured in the node configuration xml-file

Ignite does not support merging these two query entity definitions. When both 
configuration mechanisms describe the same value type, the query entity 
registered first is retained, while the subsequently supplied entity is ignored 
without any warning. The node still starts successfully and the cache remains 
operational, but part of the configured SQL schema may be missing.

For example, single-field indexes may be declared using {*}@QuerySqlField(index 
= true){*}, while a composite index for the same value type is configured 
through *queryEntities* in the node configuration. Depending on the order in 
which the corresponding setters are invoked, either the annotation-derived 
indexes or the explicitly configured indexes are NOT created.

Reproducer: [^MixedIndexConfigurationReproducer.patch]

Starting a node with such a partially applied configuration is unsafe. The 
configuration error must be detected before the cache is started.
h2. Root cause

Both *CacheConfiguration#setIndexedTypes* and 
*CacheConfiguration#setQueryEntities* store query metadata in the same internal 
*qryEntities* collection. When an entity with the same value type is already 
present, the incoming entity is treated as a duplicate and is not added (see 
{*}CacheConfiguration#setQueryEntities{*}):
{code:java}
for (QueryEntity entity : qryEntities) {
    boolean found = false;

    for (QueryEntity existing : this.qryEntities) {
        if (Objects.equals(entity.findValueType(), existing.findValueType())) {
            found = true;

            break;
        }
    }

    if (!found)
        this.qryEntities.add(entity);
}{code}
When the value type is already registered:
 * the existing and incoming entities are not merged
 * their fields and indexes are not compared
 * conflicting or additional metadata is not validated
 * the ignored configuration is not reported

The first registered query entity effectively wins.
h2. Expected behavior

Ignite must reject a cache configuration in which the same value type is 
configured through both *indexedTypes* and {*}queryEntities{*}. The node must 
fail to start with a *CacheException* instead of silently ignoring one of the 
query entity definitions. The validation must not depend on the order in which 
the configuration setters are called.
h2. Possible follow-up

Support for combining compatible query entity definitions may be considered as 
a separate improvement. Such an improvement would require explicit merge and 
conflict-resolution rules for:
 * fields and field types
 * table names
 * aliases
 * key fields
 * index names and definitions
 * other QueryEntity metadata

Until such rules are defined and implemented, fail-fast validation is prefered 
as opposed to starting a node with an incomplete SQL schema.

> Fail node startup when the same query entity is configured through 
> indexedTypes and queryEntities
> -------------------------------------------------------------------------------------------------
>
>                 Key: IGNITE-28907
>                 URL: https://issues.apache.org/jira/browse/IGNITE-28907
>             Project: Ignite
>          Issue Type: Task
>            Reporter: Oleg Valuyskiy
>            Assignee: Oleg Valuyskiy
>            Priority: Major
>              Labels: ise
>         Attachments: MixedIndexConfigurationReproducer.patch
>
>
> h2. Problem
> Apache Ignite allows the same SQL value type to be configured simultaneously 
> through:
>  * {*}CacheConfiguration#setIndexedTypes{*}, which creates a *QueryEntity* 
> from annotations such as *@QuerySqlField*
>  * {*}CacheConfiguration#setQueryEntities{*}, which supplies a *QueryEntity* 
> explicitly configured in the node configuration xml-file
> Ignite does not support merging these two query entity definitions. When both 
> configuration mechanisms describe the same value type, the query entity 
> registered first is retained, while the subsequently supplied entity is 
> ignored without any warning. The node still starts successfully and the cache 
> remains operational, but part of the configured SQL schema may be missing.
> For example, single-field indexes may be declared using 
> {*}@QuerySqlField(index = true){*}, while a composite index for the same 
> value type is configured through *queryEntities* in the node configuration. 
> Depending on the order in which the corresponding setters are invoked, either 
> the annotation-derived indexes or the explicitly configured indexes are NOT 
> created.
> Reproducer: [^MixedIndexConfigurationReproducer.patch]
> Starting a node with such a partially applied configuration is unsafe. The 
> configuration error must be detected before the cache is started.
> h2. Root cause
> Both *CacheConfiguration#setIndexedTypes* and 
> *CacheConfiguration#setQueryEntities* store query metadata in the same 
> internal *qryEntities* collection. When an entity with the same value type is 
> already present, the incoming entity is treated as a duplicate and is not 
> added (see {*}CacheConfiguration#setQueryEntities{*}):
> {code:java}
> for (QueryEntity entity : qryEntities) {
>     boolean found = false;
>     for (QueryEntity existing : this.qryEntities) {
>         if (Objects.equals(entity.findValueType(), existing.findValueType())) 
> {
>             found = true;
>             break;
>         }
>     }
>     if (!found)
>         this.qryEntities.add(entity);
> }{code}
> When the value type is already registered:
>  * the existing and incoming entities are not merged
>  * their fields and indexes are not compared
>  * conflicting or additional metadata is not validated
>  * the ignored configuration is not reported
> The first registered query entity effectively wins.
> h2. Expected behavior
> Ignite must reject a cache configuration in which the same value type is 
> configured through both *indexedTypes* and {*}queryEntities{*}. The node must 
> fail to start with a *CacheException* instead of silently ignoring one of the 
> query entity definitions. The validation must not depend on the order in 
> which the configuration setters are called.
> h2. Possible follow-up
> Support for combining compatible query entity definitions may be considered 
> as a separate improvement. Such an improvement would require explicit merge 
> and conflict-resolution rules for:
>  * fields and field types
>  * table names
>  * aliases
>  * key fields
>  * index names and definitions
>  * other QueryEntity metadata
> Until such rules are defined and implemented, fail-fast validation is 
> prefered as opposed to starting a node with an incomplete SQL schema.



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

Reply via email to