Uploaded image for project: 'Ignite'
  1. Ignite
  2. IGNITE-23170

SQL returns huge decimal values with trailing zeros

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • 3.0
    • sql

    Description

      Add the following code to ItSqlApiBaseTest

          @Test
          public void testDecimalDivisionTimeout() {
              IgniteSql igniteSql = igniteSql();
      
              igniteSql.execute(null, "CREATE TABLE testDecimalDivisionTimeout (ID INT PRIMARY KEY, VAL0 INT)").close();
              for (int i = 0; i < 10; i++) {
                  igniteSql.execute(null, "INSERT INTO testDecimalDivisionTimeout VALUES (?, ?)", i, i * 100).close();
              }
      
              ResultSet<SqlRow> cursor = igniteSql.execute(null,
                      "SELECT cast(VAl0 as decimal(300)) / ? FROM testDecimalDivisionTimeout", new BigDecimal(200));
      
              while (cursor.hasNext()) {
                  cursor.next();
              }
          }
      

      Warnings in the log:

      org.apache.ignite.lang.IgniteException: A critical thread is blocked for 1758 ms that is more than the allowed 500 ms, it is "iscsat_n_0-client-12" prio=10 Id=121 RUNNABLE
      	at java.base@11.0.24/java.math.MutableBigInteger.divideOneWord(MutableBigInteger.java:1131)
      	at java.base@11.0.24/java.math.MutableBigInteger.divideKnuth(MutableBigInteger.java:1203)
      	at java.base@11.0.24/java.math.MutableBigInteger.divideKnuth(MutableBigInteger.java:1163)
      	at java.base@11.0.24/java.math.BigInteger.divideAndRemainderKnuth(BigInteger.java:2328)
      	at java.base@11.0.24/java.math.BigInteger.divideAndRemainder(BigInteger.java:2316)
      	at java.base@11.0.24/java.math.BigDecimal.createAndStripZerosToMatchScale(BigDecimal.java:4878)
      	at java.base@11.0.24/java.math.BigDecimal.stripTrailingZeros(BigDecimal.java:3053)
      	at app//org.apache.ignite.internal.binarytuple.BinaryTupleCommon.shrinkDecimal(BinaryTupleCommon.java:118)
      	at app//org.apache.ignite.internal.binarytuple.BinaryTupleBuilder.appendDecimalNotNull(BinaryTupleBuilder.java:292)
      	at app//org.apache.ignite.internal.binarytuple.BinaryTupleBuilder.appendDecimal(BinaryTupleBuilder.java:317)
      	at app//org.apache.ignite.client.handler.requests.sql.ClientSqlCommon.packValue(ClientSqlCommon.java:96)
      	at app//org.apache.ignite.client.handler.requests.sql.ClientSqlCommon.packCurrentPage(ClientSqlCommon.java:48)
      	at app//org.apache.ignite.client.handler.requests.sql.ClientSqlExecuteRequest.writeResultSetAsync(ClientSqlExecuteRequest.java:135)
      	at app//org.apache.ignite.client.handler.requests.sql.ClientSqlExecuteRequest.lambda$process$0(ClientSqlExecuteRequest.java:93)
      

      This is caused by the fact that SQL returns a BigDecimal with ~32000 trailing zeros:

      • SqlRowHandler.toBinaryTuple returns "0.5" without trailing zeros - all good
      • Commons.readValue sets the scale to 32767, creating trailing zeros, resulting value takes ~3KB
      • ClientSqlCommon.packValue calls BinaryTupleBuilder.appendDecimal which takes quite some time to strip those trailing zeros

      While IGNITE-18922 will get rid of intermediate conversion in client handler, we still return huge values from embedded API, allocating extra memory and potentially causing issue for the users.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              ptupitsyn Pavel Tupitsyn
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated: