[
https://issues.apache.org/jira/browse/IGNITE-26491?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Pavel Pereslegin updated IGNITE-26491:
--------------------------------------
Description:
The behavior of the embedded client is inconsistent with the thin client when
trying to read a narrower integer type from tuple that contains long value.
For example, when we have table with bigint column val.
{code:sql}
create table test_int (id bigint primary key, val bigint not null)
{code}
Getting existing row from view
{code:java}
tuple = kvVIew.get(null, key);
{code}
the next
{code:java}
tuple.intValue("VAL")
{code}
in thin client produces
{noformat}
ClassCastException: Column with name 'VAL' has type INT64 but INT32 was
requested
{noformat}
but does not produces any errors in embedded client.
(need to check the same case with record view also)
Full reproducer
{code:java}
sql("create table test_int (id bigint primary key, val bigint)");
KeyValueView<Tuple, Tuple> kvVIew =
client.tables().table("test_int").keyValueView();
KeyValueView<Tuple, Tuple> kvVIewEmbedded =
CLUSTER.aliveNode().tables().table("test_int").keyValueView();
Tuple key = Tuple.create().set("id", 1L);
Tuple val = Tuple.create().set("val", 1L);
kvVIew.put(null, key, val);
Tuple thinReturnedVal = kvVIew.get(null, key);
Tuple embeddedReturnedVal = kvVIewEmbedded.get(null, key);
assertEquals(1, embeddedReturnedVal.longValue(0));
assertEquals(1, thinReturnedVal.longValue(0));
// The following statement should fail, but does not fail.
assertEquals(1, embeddedReturnedVal.intValue("VAL"));
// The following statement fails with ClassCastException.
assertEquals(1, thinReturnedVal.intValue("VAL"));
{code}
Exception stacktrace:
{noformat}
java.lang.ClassCastException: Column with name 'VAL' has type INT64 but INT32
was requested
at
org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.binaryTupleIndex(MutableTupleBinaryTupleAdapter.java:468)
at
org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.validateSchemaColumnType(MutableTupleBinaryTupleAdapter.java:477)
at
org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.intValue(MutableTupleBinaryTupleAdapter.java:202)
{noformat}
It is necessary to determine which behavior is correct and eliminate
inconsistencies.
h2. UPDATE
We want to make the behavior consistent in all clients:
# align the behavior with the [column upgrade
rules|https://docs.google.com/document/d/17dx7hKmKLMGQ460O3i4k5ZNXO9ylW1pHlCyD8xg23L0/edit?tab=t.0]
# relax current validation to support downcast where possible because we don't
want to break column upgrade scenarios
For example the following scenario should work:
* The user upgraded the column in the database from int to long, the user
application continues to treat the column as an int and this shouldn't break
application during reading or writing.
* The user updates the application
was:
The behavior of the embedded client is inconsistent with the thin client when
trying to read a narrower integer type from tuple that contains long value.
For example, when we have table with bigint column val.
{code:sql}
create table test_int (id bigint primary key, val bigint not null)
{code}
Getting existing row from view
{code:java}
tuple = kvVIew.get(null, key);
{code}
the next
{code:java}
tuple.intValue("VAL")
{code}
in thin client produces
{noformat}
ClassCastException: Column with name 'VAL' has type INT64 but INT32 was
requested
{noformat}
but does not produces any errors in embedded client.
(need to check the same case with record view also)
Full reproducer
{code:java}
sql("create table test_int (id bigint primary key, val bigint)");
KeyValueView<Tuple, Tuple> kvVIew =
client.tables().table("test_int").keyValueView();
KeyValueView<Tuple, Tuple> kvVIewEmbedded =
CLUSTER.aliveNode().tables().table("test_int").keyValueView();
Tuple key = Tuple.create().set("id", 1L);
Tuple val = Tuple.create().set("val", 1L);
kvVIew.put(null, key, val);
Tuple thinReturnedVal = kvVIew.get(null, key);
Tuple embeddedReturnedVal = kvVIewEmbedded.get(null, key);
assertEquals(1, embeddedReturnedVal.longValue(0));
assertEquals(1, thinReturnedVal.longValue(0));
// The following statement should fail, but does not fail.
assertEquals(1, embeddedReturnedVal.intValue("VAL"));
// The following statement fails with ClassCastException.
assertEquals(1, thinReturnedVal.intValue("VAL"));
{code}
Exception stacktrace:
{noformat}
java.lang.ClassCastException: Column with name 'VAL' has type INT64 but INT32
was requested
at
org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.binaryTupleIndex(MutableTupleBinaryTupleAdapter.java:468)
at
org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.validateSchemaColumnType(MutableTupleBinaryTupleAdapter.java:477)
at
org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.intValue(MutableTupleBinaryTupleAdapter.java:202)
{noformat}
It is necessary to determine which behavior is correct and eliminate
inconsistencies.
> Inconsistent behavior of thin/embedded client when reading tuple value
> ----------------------------------------------------------------------
>
> Key: IGNITE-26491
> URL: https://issues.apache.org/jira/browse/IGNITE-26491
> Project: Ignite
> Issue Type: Bug
> Components: sql ai3
> Reporter: Pavel Pereslegin
> Priority: Major
> Labels: ignite-3
>
> The behavior of the embedded client is inconsistent with the thin client when
> trying to read a narrower integer type from tuple that contains long value.
> For example, when we have table with bigint column val.
> {code:sql}
> create table test_int (id bigint primary key, val bigint not null)
> {code}
> Getting existing row from view
> {code:java}
> tuple = kvVIew.get(null, key);
> {code}
> the next
> {code:java}
> tuple.intValue("VAL")
> {code}
> in thin client produces
> {noformat}
> ClassCastException: Column with name 'VAL' has type INT64 but INT32 was
> requested
> {noformat}
> but does not produces any errors in embedded client.
> (need to check the same case with record view also)
> Full reproducer
> {code:java}
> sql("create table test_int (id bigint primary key, val bigint)");
> KeyValueView<Tuple, Tuple> kvVIew =
> client.tables().table("test_int").keyValueView();
> KeyValueView<Tuple, Tuple> kvVIewEmbedded =
> CLUSTER.aliveNode().tables().table("test_int").keyValueView();
> Tuple key = Tuple.create().set("id", 1L);
> Tuple val = Tuple.create().set("val", 1L);
> kvVIew.put(null, key, val);
> Tuple thinReturnedVal = kvVIew.get(null, key);
> Tuple embeddedReturnedVal = kvVIewEmbedded.get(null, key);
> assertEquals(1, embeddedReturnedVal.longValue(0));
> assertEquals(1, thinReturnedVal.longValue(0));
> // The following statement should fail, but does not fail.
> assertEquals(1, embeddedReturnedVal.intValue("VAL"));
> // The following statement fails with ClassCastException.
> assertEquals(1, thinReturnedVal.intValue("VAL"));
> {code}
> Exception stacktrace:
> {noformat}
> java.lang.ClassCastException: Column with name 'VAL' has type INT64 but INT32
> was requested
> at
> org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.binaryTupleIndex(MutableTupleBinaryTupleAdapter.java:468)
> at
> org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.validateSchemaColumnType(MutableTupleBinaryTupleAdapter.java:477)
> at
> org.apache.ignite.internal.client.table.MutableTupleBinaryTupleAdapter.intValue(MutableTupleBinaryTupleAdapter.java:202)
> {noformat}
> It is necessary to determine which behavior is correct and eliminate
> inconsistencies.
> h2. UPDATE
> We want to make the behavior consistent in all clients:
> # align the behavior with the [column upgrade
> rules|https://docs.google.com/document/d/17dx7hKmKLMGQ460O3i4k5ZNXO9ylW1pHlCyD8xg23L0/edit?tab=t.0]
> # relax current validation to support downcast where possible because we
> don't want to break column upgrade scenarios
> For example the following scenario should work:
> * The user upgraded the column in the database from int to long, the user
> application continues to treat the column as an int and this shouldn't break
> application during reading or writing.
> * The user updates the application
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)