Prevent insertion of cache entry if the binary field type and the type of the query entity do not match.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Prevent insertion of cache entry if the binary field type and the type of the query entity do not match.

Pavel Pereslegin
Hello Igniters.

If type of binary field does not match query entity field type we
still able to insert such entry into cache, but can't query it.
In the following example we have query entity with the UUID field
"name", but we insert String field "name" using binary object.

        IgniteCache<Object, Object> cache = grid(0).createCache(
            new CacheConfiguration<>("testCache").setQueryEntities(
                Collections.singletonList(
                    new QueryEntity()
                        .setKeyFieldName("id")
                        .setValueType("Person")
                        .setFields(new LinkedHashMap<>(
                            F.asMap("id", "java.lang.Integer",
                                "name", "java.util.UUID"))))));

        BinaryObject obj = grid(0).binary().builder("Person")
            .setField("id", 1)
            .setField("name", UUID.randomUUID().toString())
            .build();

        cache.put(1, obj);
        assertEquals(obj, cache.withKeepBinary().get(1));

        String sql = "select id, name from Person where id=1";

        grid(0).context().query()
            .querySqlFields(new
SqlFieldsQuery(sql).setSchema("testCache"), true)
            .getAll(); // java.lang.ClassCastException:
java.lang.String cannot be cast to java.util.UUID

The object was successfully inserted, but the "name"-field cannot be
read using sql.

Should it be better to prevent insertion of cache entry if the binary
field type and the type of the query entity field do not match?
Reply | Threaded
Open this post in threaded view
|

Re: Prevent insertion of cache entry if the binary field type and the type of the query entity do not match.

Ilya Kasnacheev
Hello!

I'm not aware about any mechanism like this one built in Apache Ignite.

I advise you to wrap Ignite's APIs into ones of your own and avoid using
raw Ignite API. This way you will make sure to do these checks on your own.

Regards,
--
Ilya Kasnacheev


пн, 25 мая 2020 г. в 15:22, Pavel Pereslegin <[hidden email]>:

> Hello Igniters.
>
> If type of binary field does not match query entity field type we
> still able to insert such entry into cache, but can't query it.
> In the following example we have query entity with the UUID field
> "name", but we insert String field "name" using binary object.
>
>         IgniteCache<Object, Object> cache = grid(0).createCache(
>             new CacheConfiguration<>("testCache").setQueryEntities(
>                 Collections.singletonList(
>                     new QueryEntity()
>                         .setKeyFieldName("id")
>                         .setValueType("Person")
>                         .setFields(new LinkedHashMap<>(
>                             F.asMap("id", "java.lang.Integer",
>                                 "name", "java.util.UUID"))))));
>
>         BinaryObject obj = grid(0).binary().builder("Person")
>             .setField("id", 1)
>             .setField("name", UUID.randomUUID().toString())
>             .build();
>
>         cache.put(1, obj);
>         assertEquals(obj, cache.withKeepBinary().get(1));
>
>         String sql = "select id, name from Person where id=1";
>
>         grid(0).context().query()
>             .querySqlFields(new
> SqlFieldsQuery(sql).setSchema("testCache"), true)
>             .getAll(); // java.lang.ClassCastException:
> java.lang.String cannot be cast to java.util.UUID
>
> The object was successfully inserted, but the "name"-field cannot be
> read using sql.
>
> Should it be better to prevent insertion of cache entry if the binary
> field type and the type of the query entity field do not match?
>
Reply | Threaded
Open this post in threaded view
|

Re: Prevent insertion of cache entry if the binary field type and the type of the query entity do not match.

Alexey Plekhanov
Pavel, Ilya,

I think we should implement such a check on insert. It can be optional (for
example enabled by property in SqlConfiguration). The sooner we found the
problem - the better.

вт, 26 мая 2020 г. в 17:56, Ilya Kasnacheev <[hidden email]>:

> Hello!
>
> I'm not aware about any mechanism like this one built in Apache Ignite.
>
> I advise you to wrap Ignite's APIs into ones of your own and avoid using
> raw Ignite API. This way you will make sure to do these checks on your own.
>
> Regards,
> --
> Ilya Kasnacheev
>
>
> пн, 25 мая 2020 г. в 15:22, Pavel Pereslegin <[hidden email]>:
>
> > Hello Igniters.
> >
> > If type of binary field does not match query entity field type we
> > still able to insert such entry into cache, but can't query it.
> > In the following example we have query entity with the UUID field
> > "name", but we insert String field "name" using binary object.
> >
> >         IgniteCache<Object, Object> cache = grid(0).createCache(
> >             new CacheConfiguration<>("testCache").setQueryEntities(
> >                 Collections.singletonList(
> >                     new QueryEntity()
> >                         .setKeyFieldName("id")
> >                         .setValueType("Person")
> >                         .setFields(new LinkedHashMap<>(
> >                             F.asMap("id", "java.lang.Integer",
> >                                 "name", "java.util.UUID"))))));
> >
> >         BinaryObject obj = grid(0).binary().builder("Person")
> >             .setField("id", 1)
> >             .setField("name", UUID.randomUUID().toString())
> >             .build();
> >
> >         cache.put(1, obj);
> >         assertEquals(obj, cache.withKeepBinary().get(1));
> >
> >         String sql = "select id, name from Person where id=1";
> >
> >         grid(0).context().query()
> >             .querySqlFields(new
> > SqlFieldsQuery(sql).setSchema("testCache"), true)
> >             .getAll(); // java.lang.ClassCastException:
> > java.lang.String cannot be cast to java.util.UUID
> >
> > The object was successfully inserted, but the "name"-field cannot be
> > read using sql.
> >
> > Should it be better to prevent insertion of cache entry if the binary
> > field type and the type of the query entity field do not match?
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Prevent insertion of cache entry if the binary field type and the type of the query entity do not match.

Ivan Daschinsky
I think this feature quite easy to implement. Before put in cache tree, we
can iterate over query descriptor fields and check whether
this field presents in binary object and if typeId is the same.
But I think there can l be a quite noticeable performance penalty when this
feature is enabled.
It should be thoroughly benchmarked.



чт, 28 мая 2020 г. в 10:22, Alex Plehanov <[hidden email]>:

> Pavel, Ilya,
>
> I think we should implement such a check on insert. It can be optional (for
> example enabled by property in SqlConfiguration). The sooner we found the
> problem - the better.
>
> вт, 26 мая 2020 г. в 17:56, Ilya Kasnacheev <[hidden email]>:
>
> > Hello!
> >
> > I'm not aware about any mechanism like this one built in Apache Ignite.
> >
> > I advise you to wrap Ignite's APIs into ones of your own and avoid using
> > raw Ignite API. This way you will make sure to do these checks on your
> own.
> >
> > Regards,
> > --
> > Ilya Kasnacheev
> >
> >
> > пн, 25 мая 2020 г. в 15:22, Pavel Pereslegin <[hidden email]>:
> >
> > > Hello Igniters.
> > >
> > > If type of binary field does not match query entity field type we
> > > still able to insert such entry into cache, but can't query it.
> > > In the following example we have query entity with the UUID field
> > > "name", but we insert String field "name" using binary object.
> > >
> > >         IgniteCache<Object, Object> cache = grid(0).createCache(
> > >             new CacheConfiguration<>("testCache").setQueryEntities(
> > >                 Collections.singletonList(
> > >                     new QueryEntity()
> > >                         .setKeyFieldName("id")
> > >                         .setValueType("Person")
> > >                         .setFields(new LinkedHashMap<>(
> > >                             F.asMap("id", "java.lang.Integer",
> > >                                 "name", "java.util.UUID"))))));
> > >
> > >         BinaryObject obj = grid(0).binary().builder("Person")
> > >             .setField("id", 1)
> > >             .setField("name", UUID.randomUUID().toString())
> > >             .build();
> > >
> > >         cache.put(1, obj);
> > >         assertEquals(obj, cache.withKeepBinary().get(1));
> > >
> > >         String sql = "select id, name from Person where id=1";
> > >
> > >         grid(0).context().query()
> > >             .querySqlFields(new
> > > SqlFieldsQuery(sql).setSchema("testCache"), true)
> > >             .getAll(); // java.lang.ClassCastException:
> > > java.lang.String cannot be cast to java.util.UUID
> > >
> > > The object was successfully inserted, but the "name"-field cannot be
> > > read using sql.
> > >
> > > Should it be better to prevent insertion of cache entry if the binary
> > > field type and the type of the query entity field do not match?
> > >
> >
>


--
Sincerely yours, Ivan Daschinskiy
Reply | Threaded
Open this post in threaded view
|

Re: Prevent insertion of cache entry if the binary field type and the type of the query entity do not match.

Sergey Kalashnikov
Guys,

I've taken the liberty of creating the ticket
(https://issues.apache.org/jira/browse/IGNITE-13110) for the proposed
changes.
I did some prototyping as well. You may find the draft code/test
changes in PR https://github.com/apache/ignite/pull/7893
Would appreciate if you can look at it and provide feedback.

Thanks a lot.
--
Sergei K.

чт, 28 мая 2020 г. в 13:45, Ivan Daschinsky <[hidden email]>:

>
> I think this feature quite easy to implement. Before put in cache tree, we
> can iterate over query descriptor fields and check whether
> this field presents in binary object and if typeId is the same.
> But I think there can l be a quite noticeable performance penalty when this
> feature is enabled.
> It should be thoroughly benchmarked.
>
>
>
> чт, 28 мая 2020 г. в 10:22, Alex Plehanov <[hidden email]>:
>
> > Pavel, Ilya,
> >
> > I think we should implement such a check on insert. It can be optional (for
> > example enabled by property in SqlConfiguration). The sooner we found the
> > problem - the better.
> >
> > вт, 26 мая 2020 г. в 17:56, Ilya Kasnacheev <[hidden email]>:
> >
> > > Hello!
> > >
> > > I'm not aware about any mechanism like this one built in Apache Ignite.
> > >
> > > I advise you to wrap Ignite's APIs into ones of your own and avoid using
> > > raw Ignite API. This way you will make sure to do these checks on your
> > own.
> > >
> > > Regards,
> > > --
> > > Ilya Kasnacheev
> > >
> > >
> > > пн, 25 мая 2020 г. в 15:22, Pavel Pereslegin <[hidden email]>:
> > >
> > > > Hello Igniters.
> > > >
> > > > If type of binary field does not match query entity field type we
> > > > still able to insert such entry into cache, but can't query it.
> > > > In the following example we have query entity with the UUID field
> > > > "name", but we insert String field "name" using binary object.
> > > >
> > > >         IgniteCache<Object, Object> cache = grid(0).createCache(
> > > >             new CacheConfiguration<>("testCache").setQueryEntities(
> > > >                 Collections.singletonList(
> > > >                     new QueryEntity()
> > > >                         .setKeyFieldName("id")
> > > >                         .setValueType("Person")
> > > >                         .setFields(new LinkedHashMap<>(
> > > >                             F.asMap("id", "java.lang.Integer",
> > > >                                 "name", "java.util.UUID"))))));
> > > >
> > > >         BinaryObject obj = grid(0).binary().builder("Person")
> > > >             .setField("id", 1)
> > > >             .setField("name", UUID.randomUUID().toString())
> > > >             .build();
> > > >
> > > >         cache.put(1, obj);
> > > >         assertEquals(obj, cache.withKeepBinary().get(1));
> > > >
> > > >         String sql = "select id, name from Person where id=1";
> > > >
> > > >         grid(0).context().query()
> > > >             .querySqlFields(new
> > > > SqlFieldsQuery(sql).setSchema("testCache"), true)
> > > >             .getAll(); // java.lang.ClassCastException:
> > > > java.lang.String cannot be cast to java.util.UUID
> > > >
> > > > The object was successfully inserted, but the "name"-field cannot be
> > > > read using sql.
> > > >
> > > > Should it be better to prevent insertion of cache entry if the binary
> > > > field type and the type of the query entity field do not match?
> > > >
> > >
> >
>
>
> --
> Sincerely yours, Ivan Daschinskiy