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

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


The following commit(s) were added to refs/heads/master by this push:
     new 16ef874  HIVE-23307: Cache ColumnIndex in HiveBaseResultSet (David 
Mollitor, reviewed by Naveen Gangam)
16ef874 is described below

commit 16ef87444a18a74f296b50c38b53b57f074b5280
Author: David Mollitor <dmolli...@apache.org>
AuthorDate: Thu May 7 10:06:09 2020 -0400

    HIVE-23307: Cache ColumnIndex in HiveBaseResultSet (David Mollitor, 
reviewed by Naveen Gangam)
---
 .../org/apache/hive/jdbc/HiveBaseResultSet.java    | 19 +++--
 .../apache/hive/jdbc/TestHiveBaseResultSet.java    | 93 ++++++++++++++++++++++
 2 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveBaseResultSet.java 
b/jdbc/src/java/org/apache/hive/jdbc/HiveBaseResultSet.java
index a69ea95..45de932 100644
--- a/jdbc/src/java/org/apache/hive/jdbc/HiveBaseResultSet.java
+++ b/jdbc/src/java/org/apache/hive/jdbc/HiveBaseResultSet.java
@@ -42,6 +42,7 @@ import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -65,6 +66,7 @@ public abstract class HiveBaseResultSet implements ResultSet {
   protected List<String> normalizedColumnNames;
   protected List<String> columnTypes;
   protected List<JdbcColumnAttributes> columnAttributes;
+  private final Map<String, Integer> columnNameIndexCache = new HashMap<>();
 
   private TableSchema schema;
 
@@ -95,19 +97,26 @@ public abstract class HiveBaseResultSet implements 
ResultSet {
 
   @Override
   public int findColumn(final String columnName) throws SQLException {
-    int columnIndex = 0;
-    if (columnName != null) {
-      final String lcColumnName = columnName.toLowerCase();
+    if (columnName == null) {
+      throw new SQLException("null column name not supported");
+    }
+    final String lcColumnName = columnName.toLowerCase();
+    final Integer result = 
this.columnNameIndexCache.computeIfAbsent(lcColumnName, cn -> {
+      int columnIndex = 0;
       for (final String normalizedColumnName : normalizedColumnNames) {
         ++columnIndex;
         final int idx = normalizedColumnName.lastIndexOf('.');
         final String name = (idx == -1) ? normalizedColumnName : 
normalizedColumnName.substring(1 + idx);
-        if (name.equals(lcColumnName) || 
normalizedColumnName.equals(lcColumnName)) {
+        if (name.equals(cn) || normalizedColumnName.equals(cn)) {
           return columnIndex;
         }
       }
+      return null;
+    });
+    if (result == null) {
+      throw new SQLException("Could not find " + columnName + " in " + 
normalizedColumnNames);
     }
-    throw new SQLException("Could not find " + columnName + " in " + 
normalizedColumnNames);
+    return result.intValue();
   }
 
   @Override
diff --git a/jdbc/src/test/org/apache/hive/jdbc/TestHiveBaseResultSet.java 
b/jdbc/src/test/org/apache/hive/jdbc/TestHiveBaseResultSet.java
index 9d42317..bca26f3 100644
--- a/jdbc/src/test/org/apache/hive/jdbc/TestHiveBaseResultSet.java
+++ b/jdbc/src/test/org/apache/hive/jdbc/TestHiveBaseResultSet.java
@@ -20,9 +20,11 @@ package org.apache.hive.jdbc;
 
 import static org.mockito.Mockito.when;
 
+import java.lang.reflect.Field;
 import java.nio.charset.StandardCharsets;
 import java.sql.SQLException;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 
 import org.apache.hadoop.hive.metastore.api.FieldSchema;
@@ -30,6 +32,7 @@ import org.apache.hive.service.cli.TableSchema;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.FieldSetter;
 
 /**
  * Test suite for {@link HiveBaseResultSet} class.
@@ -237,4 +240,94 @@ public class TestHiveBaseResultSet {
     Assert.assertFalse(resultSet.wasNull());
   }
 
+  @Test
+  public void testFindColumnUnqualified() throws Exception {
+    FieldSchema fieldSchema1 = new FieldSchema();
+    fieldSchema1.setType("int");
+
+    FieldSchema fieldSchema2 = new FieldSchema();
+    fieldSchema2.setType("int");
+
+    FieldSchema fieldSchema3 = new FieldSchema();
+    fieldSchema3.setType("int");
+
+    List<FieldSchema> fieldSchemas = Arrays.asList(fieldSchema1, fieldSchema2, 
fieldSchema3);
+    TableSchema schema = new TableSchema(fieldSchemas);
+
+    HiveBaseResultSet resultSet = Mockito.mock(HiveBaseResultSet.class);
+    resultSet.row = new Object[] { new Integer(1), new Integer(2), new 
Integer(3) };
+    resultSet.normalizedColumnNames = Arrays.asList("one", "two", "three");
+
+    Field executorField = 
HiveBaseResultSet.class.getDeclaredField("columnNameIndexCache");
+    FieldSetter.setField(resultSet, executorField, new HashMap<>());
+
+    when(resultSet.getSchema()).thenReturn(schema);
+    when(resultSet.findColumn("one")).thenCallRealMethod();
+    when(resultSet.findColumn("Two")).thenCallRealMethod();
+    when(resultSet.findColumn("THREE")).thenCallRealMethod();
+
+    Assert.assertEquals(1, resultSet.findColumn("one"));
+    Assert.assertEquals(2, resultSet.findColumn("Two"));
+    Assert.assertEquals(3, resultSet.findColumn("THREE"));
+  }
+
+  @Test
+  public void testFindColumnQualified() throws Exception {
+    FieldSchema fieldSchema1 = new FieldSchema();
+    fieldSchema1.setType("int");
+
+    FieldSchema fieldSchema2 = new FieldSchema();
+    fieldSchema2.setType("int");
+
+    FieldSchema fieldSchema3 = new FieldSchema();
+    fieldSchema3.setType("int");
+
+    List<FieldSchema> fieldSchemas = Arrays.asList(fieldSchema1, fieldSchema2, 
fieldSchema3);
+    TableSchema schema = new TableSchema(fieldSchemas);
+
+    HiveBaseResultSet resultSet = Mockito.mock(HiveBaseResultSet.class);
+    resultSet.row = new Object[] { new Integer(1), new Integer(2), new 
Integer(3) };
+    resultSet.normalizedColumnNames = Arrays.asList("table.one", "table.two", 
"table.three");
+
+    Field executorField = 
HiveBaseResultSet.class.getDeclaredField("columnNameIndexCache");
+    FieldSetter.setField(resultSet, executorField, new HashMap<>());
+
+    when(resultSet.getSchema()).thenReturn(schema);
+    when(resultSet.findColumn("one")).thenCallRealMethod();
+    when(resultSet.findColumn("Two")).thenCallRealMethod();
+    when(resultSet.findColumn("THREE")).thenCallRealMethod();
+
+    Assert.assertEquals(1, resultSet.findColumn("one"));
+    Assert.assertEquals(2, resultSet.findColumn("Two"));
+    Assert.assertEquals(3, resultSet.findColumn("THREE"));
+  }
+
+  @Test(expected = SQLException.class)
+  public void testFindColumnNull() throws Exception {
+    HiveBaseResultSet resultSet = Mockito.mock(HiveBaseResultSet.class);
+    when(resultSet.findColumn(null)).thenCallRealMethod();
+    Assert.assertEquals(0, resultSet.findColumn(null));
+  }
+
+  @Test(expected = SQLException.class)
+  public void testFindColumnUnknownColumn() throws Exception {
+    FieldSchema fieldSchema1 = new FieldSchema();
+    fieldSchema1.setType("int");
+
+    List<FieldSchema> fieldSchemas = Arrays.asList(fieldSchema1);
+    TableSchema schema = new TableSchema(fieldSchemas);
+
+    HiveBaseResultSet resultSet = Mockito.mock(HiveBaseResultSet.class);
+    resultSet.row = new Object[] { new Integer(1) };
+    resultSet.normalizedColumnNames = Arrays.asList("table.one");
+
+    Field executorField = 
HiveBaseResultSet.class.getDeclaredField("columnNameIndexCache");
+    FieldSetter.setField(resultSet, executorField, new HashMap<>());
+
+    when(resultSet.getSchema()).thenReturn(schema);
+    when(resultSet.findColumn("zero")).thenCallRealMethod();
+
+    Assert.assertEquals(1, resultSet.findColumn("zero"));
+  }
+
 }

Reply via email to