[
https://issues.apache.org/jira/browse/IGNITE-27739?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Maksim Zhuravkov updated IGNITE-27739:
--------------------------------------
Description:
In some cases client's KeyValueView ignores precision specified in a column
definition and allows to insert values with larger precision than it is allowed
by column's type.
In the following example operations with kv1 and kv2 behave differently:
{noformat}
import java.math.BigDecimal;
import java.util.Map;
import org.apache.ignite.Ignite;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.internal.ClusterPerClassIntegrationTest;
import org.apache.ignite.sql.IgniteSql;
import org.apache.ignite.table.KeyValueView;
import org.apache.ignite.table.Table;
import org.apache.ignite.table.Tuple;
import org.apache.ignite.tx.Transaction;
import org.junit.jupiter.api.Test;
public class BigDecimalExample extends ClusterPerClassIntegrationTest {
@Test
public void client() {
try (IgniteClient client =
IgniteClient.builder().addresses("localhost:10800").build()) {
example(client);
}
}
@Test
public void embedded() {
Ignite node = node(0);
example(node);
}
private static void example(Ignite ignite) {
IgniteSql sql = ignite.sql();
sql.executeScript("" +
"DROP TABLE IF EXISTS kv1;" +
"CREATE TABLE kv1 (key INT, val DECIMAL(10,2), PRIMARY KEY
(key) );" +
"DROP TABLE IF EXISTS kv2;" +
"CREATE TABLE kv2 (key INT, str VARCHAR(10), val DECIMAL(10,2),
PRIMARY KEY (key) )"
);
execute(ignite, "kv1");
System.err.println("----");
execute(ignite, "kv2");
}
private static void execute(Ignite client, String tableName) {
Table table = client.tables().table(tableName);
KeyValueView<Tuple, Tuple> view = table.keyValueView();
Tuple key = Tuple.create(Map.of("key", 1));
Tuple value = Tuple.create(Map.of("val", new
BigDecimal("11223344556677889900.123456")));
try {
view.put(null, key, value);
System.err.println("KV PUT OK>");
} catch (Exception e) {
System.err.println("KV PUT ERROR>" + e);
}
System.err.println("KV GET>" + view.get(null, key));
IgniteSql sql = client.sql();
try {
try (var rs = sql.execute((Transaction) null,
"INSERT INTO " + tableName + "(key, val) VALUES(2,
11223344556677889900.123456)")) {
System.err.println("SQL INSERT OK>" + rs.affectedRows());
}
} catch (Exception e) {
System.err.println("SQL INSERT ERROR>" + e);
}
}
}
{noformat}
Output for client - a put operation on kv1 completes, but fails on kv2.
{noformat}
KV PUT OK>
KV GET>ClientTuple [VAL=11223344556677889900.12]
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:40a67096
----
KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
Failed to serialize row for table PUBLIC.KV2. Numeric field overflow in column
'VAL' TraceId:35ebfc49
KV GET>null
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:ba9bf72e
{noformat}
Output for embedded - no difference between kv1 and kv2
{noformat}
KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
Failed to serialize row for table PUBLIC.KV1. Numeric field overflow in column
'VAL' TraceId:1d10e96a
KV GET>null
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:3d5453d2
----
KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
Failed to serialize row for table PUBLIC.KV2. Numeric field overflow in column
'VAL' TraceId:ea684975
KV GET>null
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:5480b1d3
{noformat}
was:
Client's KeyValueView ignores precision specified in a column definition and
allows into insert values with larger precision than it is allowed by column's
type in some cases.
In the following example operations with kv1 and kv2 behave differently:
{noformat}
import java.math.BigDecimal;
import java.util.Map;
import org.apache.ignite.Ignite;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.internal.ClusterPerClassIntegrationTest;
import org.apache.ignite.sql.IgniteSql;
import org.apache.ignite.table.KeyValueView;
import org.apache.ignite.table.Table;
import org.apache.ignite.table.Tuple;
import org.apache.ignite.tx.Transaction;
import org.junit.jupiter.api.Test;
public class BigDecimalExample extends ClusterPerClassIntegrationTest {
@Test
public void client() {
try (IgniteClient client =
IgniteClient.builder().addresses("localhost:10800").build()) {
example(client);
}
}
@Test
public void embedded() {
Ignite node = node(0);
example(node);
}
private static void example(Ignite ignite) {
IgniteSql sql = ignite.sql();
sql.executeScript("" +
"DROP TABLE IF EXISTS kv1;" +
"CREATE TABLE kv1 (key INT, val DECIMAL(10,2), PRIMARY KEY
(key) );" +
"DROP TABLE IF EXISTS kv2;" +
"CREATE TABLE kv2 (key INT, str VARCHAR(10), val DECIMAL(10,2),
PRIMARY KEY (key) )"
);
execute(ignite, "kv1");
System.err.println("----");
execute(ignite, "kv2");
}
private static void execute(Ignite client, String tableName) {
Table table = client.tables().table(tableName);
KeyValueView<Tuple, Tuple> view = table.keyValueView();
Tuple key = Tuple.create(Map.of("key", 1));
Tuple value = Tuple.create(Map.of("val", new
BigDecimal("11223344556677889900.123456")));
try {
view.put(null, key, value);
System.err.println("KV PUT OK>");
} catch (Exception e) {
System.err.println("KV PUT ERROR>" + e);
}
System.err.println("KV GET>" + view.get(null, key));
IgniteSql sql = client.sql();
try {
try (var rs = sql.execute((Transaction) null,
"INSERT INTO " + tableName + "(key, val) VALUES(2,
11223344556677889900.123456)")) {
System.err.println("SQL INSERT OK>" + rs.affectedRows());
}
} catch (Exception e) {
System.err.println("SQL INSERT ERROR>" + e);
}
}
}
{noformat}
Output for client - a put operation on kv1 completes, but fails on kv2.
{noformat}
KV PUT OK>
KV GET>ClientTuple [VAL=11223344556677889900.12]
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:40a67096
----
KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
Failed to serialize row for table PUBLIC.KV2. Numeric field overflow in column
'VAL' TraceId:35ebfc49
KV GET>null
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:ba9bf72e
{noformat}
Output for embedded - no difference between kv1 and kv2
{noformat}
KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
Failed to serialize row for table PUBLIC.KV1. Numeric field overflow in column
'VAL' TraceId:1d10e96a
KV GET>null
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:3d5453d2
----
KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
Failed to serialize row for table PUBLIC.KV2. Numeric field overflow in column
'VAL' TraceId:ea684975
KV GET>null
SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
overflow. A field with precision 10, scale 2 must round to an absolute value
less than 10^8. TraceId:5480b1d3
{noformat}
> Thin client. KeyValueView put ignores decimal precision in some cases
> ---------------------------------------------------------------------
>
> Key: IGNITE-27739
> URL: https://issues.apache.org/jira/browse/IGNITE-27739
> Project: Ignite
> Issue Type: Bug
> Components: thin clients ai3
> Affects Versions: 3.1
> Reporter: Maksim Zhuravkov
> Priority: Major
> Labels: ignite-3
>
> In some cases client's KeyValueView ignores precision specified in a column
> definition and allows to insert values with larger precision than it is
> allowed by column's type.
> In the following example operations with kv1 and kv2 behave differently:
> {noformat}
> import java.math.BigDecimal;
> import java.util.Map;
> import org.apache.ignite.Ignite;
> import org.apache.ignite.client.IgniteClient;
> import org.apache.ignite.internal.ClusterPerClassIntegrationTest;
> import org.apache.ignite.sql.IgniteSql;
> import org.apache.ignite.table.KeyValueView;
> import org.apache.ignite.table.Table;
> import org.apache.ignite.table.Tuple;
> import org.apache.ignite.tx.Transaction;
> import org.junit.jupiter.api.Test;
> public class BigDecimalExample extends ClusterPerClassIntegrationTest {
> @Test
> public void client() {
> try (IgniteClient client =
> IgniteClient.builder().addresses("localhost:10800").build()) {
> example(client);
> }
> }
> @Test
> public void embedded() {
> Ignite node = node(0);
> example(node);
> }
> private static void example(Ignite ignite) {
> IgniteSql sql = ignite.sql();
>
> sql.executeScript("" +
> "DROP TABLE IF EXISTS kv1;" +
> "CREATE TABLE kv1 (key INT, val DECIMAL(10,2), PRIMARY KEY
> (key) );" +
> "DROP TABLE IF EXISTS kv2;" +
> "CREATE TABLE kv2 (key INT, str VARCHAR(10), val
> DECIMAL(10,2), PRIMARY KEY (key) )"
> );
> execute(ignite, "kv1");
> System.err.println("----");
> execute(ignite, "kv2");
> }
> private static void execute(Ignite client, String tableName) {
> Table table = client.tables().table(tableName);
> KeyValueView<Tuple, Tuple> view = table.keyValueView();
> Tuple key = Tuple.create(Map.of("key", 1));
> Tuple value = Tuple.create(Map.of("val", new
> BigDecimal("11223344556677889900.123456")));
> try {
> view.put(null, key, value);
> System.err.println("KV PUT OK>");
> } catch (Exception e) {
> System.err.println("KV PUT ERROR>" + e);
> }
> System.err.println("KV GET>" + view.get(null, key));
> IgniteSql sql = client.sql();
> try {
> try (var rs = sql.execute((Transaction) null,
> "INSERT INTO " + tableName + "(key, val) VALUES(2,
> 11223344556677889900.123456)")) {
> System.err.println("SQL INSERT OK>" + rs.affectedRows());
> }
> } catch (Exception e) {
> System.err.println("SQL INSERT ERROR>" + e);
> }
> }
> }
> {noformat}
> Output for client - a put operation on kv1 completes, but fails on kv2.
> {noformat}
> KV PUT OK>
> KV GET>ClientTuple [VAL=11223344556677889900.12]
> SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
> overflow. A field with precision 10, scale 2 must round to an absolute value
> less than 10^8. TraceId:40a67096
> ----
> KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
> Failed to serialize row for table PUBLIC.KV2. Numeric field overflow in
> column 'VAL' TraceId:35ebfc49
> KV GET>null
> SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
> overflow. A field with precision 10, scale 2 must round to an absolute value
> less than 10^8. TraceId:ba9bf72e
> {noformat}
> Output for embedded - no difference between kv1 and kv2
> {noformat}
> KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
> Failed to serialize row for table PUBLIC.KV1. Numeric field overflow in
> column 'VAL' TraceId:1d10e96a
> KV GET>null
> SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
> overflow. A field with precision 10, scale 2 must round to an absolute value
> less than 10^8. TraceId:3d5453d2
> ----
> KV PUT ERROR>org.apache.ignite.lang.MarshallerException: IGN-MARSHALLING-1
> Failed to serialize row for table PUBLIC.KV2. Numeric field overflow in
> column 'VAL' TraceId:ea684975
> KV GET>null
> SQL INSERT ERROR>org.apache.ignite.sql.SqlException: IGN-SQL-7 Numeric field
> overflow. A field with precision 10, scale 2 must round to an absolute value
> less than 10^8. TraceId:5480b1d3
> {noformat}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)