This is an automated email from the ASF dual-hosted git repository.

cgivre pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git


The following commit(s) were added to refs/heads/master by this push:
     new 82fc42e  DRILL-7887: JDBC plugin returns incorrect precision for 
SUM(DECIMAL) queries
82fc42e is described below

commit 82fc42ef3e22de84893faa5f5fcaa44c9dae2046
Author: Volodymyr Vysotskyi <[email protected]>
AuthorDate: Sat Mar 27 14:50:58 2021 +0200

    DRILL-7887: JDBC plugin returns incorrect precision for SUM(DECIMAL) queries
---
 .../drill/exec/store/jdbc/JdbcRecordReader.java    | 14 +++++++++++--
 .../exec/store/jdbc/TestJdbcPluginWithMySQLIT.java | 24 ++++++++++++++++++++++
 .../src/test/resources/mysql-test-data.sql         |  5 +++--
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git 
a/contrib/storage-jdbc/src/main/java/org/apache/drill/exec/store/jdbc/JdbcRecordReader.java
 
b/contrib/storage-jdbc/src/main/java/org/apache/drill/exec/store/jdbc/JdbcRecordReader.java
old mode 100755
new mode 100644
index 7966ca0..a77de8d
--- 
a/contrib/storage-jdbc/src/main/java/org/apache/drill/exec/store/jdbc/JdbcRecordReader.java
+++ 
b/contrib/storage-jdbc/src/main/java/org/apache/drill/exec/store/jdbc/JdbcRecordReader.java
@@ -64,6 +64,8 @@ import 
org.apache.drill.shaded.guava.com.google.common.collect.ImmutableMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static 
org.apache.drill.exec.planner.types.DrillRelDataTypeSystem.DRILL_REL_DATATYPE_SYSTEM;
+
 class JdbcRecordReader extends AbstractRecordReader {
 
   private static final Logger logger = 
LoggerFactory.getLogger(JdbcRecordReader.class);
@@ -210,8 +212,8 @@ class JdbcRecordReader extends AbstractRecordReader {
         String name = columns.get(i - 1).getRootSegmentPath();
         // column index in ResultSetMetaData starts from 1
         int jdbcType = meta.getColumnType(i);
-        int width = meta.getPrecision(i);
-        int scale = meta.getScale(i);
+        int width = Math.min(meta.getPrecision(i), 
DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision());
+        int scale = Math.min(meta.getScale(i), 
DRILL_REL_DATATYPE_SYSTEM.getMaxNumericScale());
         MinorType minorType = JDBC_TYPE_MAPPINGS.get(jdbcType);
         if (minorType == null) {
           logger.warn("Ignoring column that is unsupported.", UserException
@@ -381,6 +383,14 @@ class JdbcRecordReader extends AbstractRecordReader {
     void copy(int index) throws SQLException {
       BigDecimal decimal = result.getBigDecimal(columnIndex);
       if (decimal != null) {
+        if (decimal.precision() > 
DRILL_REL_DATATYPE_SYSTEM.getMaxNumericPrecision()
+            || decimal.scale() > 
DRILL_REL_DATATYPE_SYSTEM.getMaxNumericScale()) {
+          throw UserException.unsupportedError()
+              .message("Drill doesn't support reading values with precision or 
scale larger than 38.\n" +
+                  "Please use round() UDF to obtain results with supported 
precision")
+              .addContext("Column index", index)
+              .build(logger);
+        }
         mutator.setSafe(index, decimal);
       }
     }
diff --git 
a/contrib/storage-jdbc/src/test/java/org/apache/drill/exec/store/jdbc/TestJdbcPluginWithMySQLIT.java
 
b/contrib/storage-jdbc/src/test/java/org/apache/drill/exec/store/jdbc/TestJdbcPluginWithMySQLIT.java
index 543f3ad..fab2faa 100644
--- 
a/contrib/storage-jdbc/src/test/java/org/apache/drill/exec/store/jdbc/TestJdbcPluginWithMySQLIT.java
+++ 
b/contrib/storage-jdbc/src/test/java/org/apache/drill/exec/store/jdbc/TestJdbcPluginWithMySQLIT.java
@@ -23,10 +23,16 @@ import com.wix.mysql.config.MysqldConfig;
 import com.wix.mysql.config.SchemaConfig;
 import com.wix.mysql.distribution.Version;
 import org.apache.drill.categories.JdbcStorageTest;
+import org.apache.drill.common.types.TypeProtos;
 import org.apache.drill.exec.expr.fn.impl.DateUtility;
+import org.apache.drill.exec.physical.rowSet.DirectRowSet;
+import org.apache.drill.exec.physical.rowSet.RowSet;
+import org.apache.drill.exec.record.metadata.SchemaBuilder;
+import org.apache.drill.exec.record.metadata.TupleMetadata;
 import org.apache.drill.test.ClusterFixture;
 import org.apache.drill.test.ClusterTest;
 import org.apache.drill.test.QueryTestUtil;
+import org.apache.drill.test.rowSet.RowSetUtilities;
 import org.joda.time.DateTimeZone;
 import org.junit.AfterClass;
 import org.junit.Assume;
@@ -198,6 +204,24 @@ public class TestJdbcPluginWithMySQLIT extends ClusterTest 
{
   }
 
   @Test
+  public void pushDownAggWithDecimal() throws Exception {
+    String query = "SELECT sum(decimal_field * smallint_field) AS 
`order_total`\n" +
+        "FROM mysql.`drill_mysql_test`.person e";
+
+    DirectRowSet results = queryBuilder().sql(query).rowSet();
+
+    TupleMetadata expectedSchema = new SchemaBuilder()
+        .addNullable("order_total", TypeProtos.MinorType.VARDECIMAL, 38, 2)
+        .buildSchema();
+
+    RowSet expected = client.rowSetBuilder(expectedSchema)
+        .addRow(123.32)
+        .build();
+
+    RowSetUtilities.verify(expected, results);
+  }
+
+  @Test
   public void testPhysicalPlanSubmission() throws Exception {
     String query = "select * from mysql.`drill_mysql_test`.person";
     String plan = queryBuilder().sql(query).explainJson();
diff --git a/contrib/storage-jdbc/src/test/resources/mysql-test-data.sql 
b/contrib/storage-jdbc/src/test/resources/mysql-test-data.sql
index b1af4d1..f108762 100644
--- a/contrib/storage-jdbc/src/test/resources/mysql-test-data.sql
+++ b/contrib/storage-jdbc/src/test/resources/mysql-test-data.sql
@@ -38,6 +38,7 @@ create table person (
   long_text_field LONGTEXT,
   blob_field      BLOB,
   bit_field       BIT,
+  decimal_field   DECIMAL(15, 2),
 
   enum_field      ENUM('XXX', 'YYY', 'ZZZ') NOT NULL
 );
@@ -47,7 +48,7 @@ insert into person (first_name, last_name, address, city, 
state, zip, bigint_fie
                     time_field, timestamp_field, date_field, datetime_field, 
year_field,
                     json,
                     text_field, tiny_text_field, medium_text_field, 
long_text_field, blob_field, bit_field,
-                    enum_field)
+                    decimal_field, enum_field)
     values ('first_name_1', 'last_name_1', '1401 John F Kennedy Blvd', 
'Philadelphia', 'PA', 19107, 123456789, 1, 10.01,
             false, 1.0, 1.1, 1.2,
             '13:00:01', '2012-02-29 13:00:01', '2012-02-29', '2012-02-29 
13:00:01', 2015,
@@ -56,7 +57,7 @@ insert into person (first_name, last_name, address, city, 
state, zip, bigint_fie
             'a medium piece of text', 'a longer piece of text this is going 
on.....',
             'this is a test',
             1,
-            'XXX');
+            123.321, 'XXX');
 
 insert into person (first_name, last_name, address, city, state, zip, 
bigint_field, smallint_field, numeric_field,
                     boolean_field, double_field, float_field, real_field,

Reply via email to