Repository: calcite-avatica
Updated Branches:
  refs/heads/master 2ca9c383f -> 4b7eee5bf


[CALCITE-2386] Naively wire up struct support

Closes #62

Signed-off-by: Josh Elser <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/calcite-avatica/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite-avatica/commit/4b7eee5b
Tree: http://git-wip-us.apache.org/repos/asf/calcite-avatica/tree/4b7eee5b
Diff: http://git-wip-us.apache.org/repos/asf/calcite-avatica/diff/4b7eee5b

Branch: refs/heads/master
Commit: 4b7eee5bf430b916c7c07897b6f60d2b6b6dabb7
Parents: 2ca9c38
Author: Kenneth Knowles <[email protected]>
Authored: Wed Jun 27 05:49:11 2018 -0700
Committer: Josh Elser <[email protected]>
Committed: Thu Jun 28 15:54:00 2018 -0400

----------------------------------------------------------------------
 .../org/apache/calcite/avatica/AvaticaSite.java |  3 +-
 .../apache/calcite/avatica/util/ArrayImpl.java  | 12 +++
 .../org/apache/calcite/avatica/util/Cursor.java |  3 +
 .../AvaticaResultSetConversionsTest.java        | 91 ++++++++++++++++++--
 4 files changed, 103 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/4b7eee5b/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java 
b/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
index ece9e04..b7f46a0 100644
--- a/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
+++ b/core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java
@@ -298,8 +298,9 @@ public class AvaticaSite {
     case Types.NCLOB:
     case Types.REF:
     case Types.SQLXML:
-    case Types.STRUCT:
       throw notImplemented();
+    case Types.STRUCT:
+      return accessor.getStruct();
     case Types.ARRAY:
       return accessor.getArray();
     case Types.BIGINT:

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/4b7eee5b/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java 
b/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
index ccb0af9..bb43607 100644
--- a/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
+++ b/core/src/main/java/org/apache/calcite/avatica/util/ArrayImpl.java
@@ -26,6 +26,7 @@ import java.sql.Types;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 /** Implementation of JDBC {@link Array}. */
 public class ArrayImpl implements Array {
@@ -220,6 +221,17 @@ public class ArrayImpl implements Array {
     // nothing to do
   }
 
+  public static boolean equalContents(Array left, Array right) throws 
SQLException {
+    ResultSet leftResultSet = left.getResultSet();
+    ResultSet rightResultSet = right.getResultSet();
+    while (leftResultSet.next() && rightResultSet.next()) {
+      if (!Objects.equals(leftResultSet.getObject(1), 
rightResultSet.getObject(1))) {
+        return false;
+      }
+    }
+    return !leftResultSet.next() && !rightResultSet.next();
+  }
+
   /** Factory that can create a ResultSet or Array based on a stream of 
values. */
   public interface Factory {
 

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/4b7eee5b/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java 
b/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
index 8eab72f..7ba605d 100644
--- a/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
+++ b/core/src/main/java/org/apache/calcite/avatica/util/Cursor.java
@@ -30,6 +30,7 @@ import java.sql.NClob;
 import java.sql.Ref;
 import java.sql.SQLException;
 import java.sql.SQLXML;
+import java.sql.Struct;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
@@ -122,6 +123,8 @@ public interface Cursor extends AutoCloseable {
 
     Array getArray() throws SQLException;
 
+    Struct getStruct() throws SQLException;
+
     Date getDate(Calendar calendar) throws SQLException;
 
     Time getTime(Calendar calendar) throws SQLException;

http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/4b7eee5b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
 
b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
index 500acbb..d07b5f3 100644
--- 
a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
+++ 
b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java
@@ -17,7 +17,11 @@
 package org.apache.calcite.avatica;
 
 import org.apache.calcite.avatica.remote.TypedValue;
+import org.apache.calcite.avatica.util.ArrayFactoryImpl;
+import org.apache.calcite.avatica.util.ArrayImpl;
 import org.apache.calcite.avatica.util.DateTimeUtils;
+import org.apache.calcite.avatica.util.StructImpl;
+import org.apache.calcite.avatica.util.Unsafe;
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -42,6 +46,7 @@ import java.sql.ResultSet;
 import java.sql.SQLDataException;
 import java.sql.SQLException;
 import java.sql.SQLXML;
+import java.sql.Struct;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
@@ -56,6 +61,7 @@ import java.util.Properties;
 import static org.hamcrest.CoreMatchers.isA;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 /**
@@ -147,13 +153,34 @@ public class AvaticaResultSetConversionsTest {
           columnMetaData("timestamp", 10,
               ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
                   ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP),
+              DatabaseMetaData.columnNoNulls),
+          columnMetaData("array", 11,
+              ColumnMetaData.array(
+                  ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
+                      ColumnMetaData.Rep.PRIMITIVE_INT),
+                  "ARRAY",
+                  ColumnMetaData.Rep.ARRAY),
+              DatabaseMetaData.columnNoNulls),
+          columnMetaData("struct", 12,
+              ColumnMetaData.struct(
+                  Arrays.asList(
+                      columnMetaData("int", 0,
+                          ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
+                              ColumnMetaData.Rep.PRIMITIVE_INT),
+                          DatabaseMetaData.columnNoNulls),
+                      columnMetaData("bool", 1,
+                          ColumnMetaData.scalar(Types.BOOLEAN, "BOOLEAN",
+                              ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
+                          DatabaseMetaData.columnNoNulls))),
               DatabaseMetaData.columnNoNulls));
 
       List<Object> row = Collections.<Object>singletonList(
           new Object[] {
               true, (byte) 1, (short) 2, 3, 4L, 5.0f, 6.0d, "testvalue",
               new Date(1476130718123L), new Time(1476130718123L),
-              new Timestamp(1476130718123L)
+              new Timestamp(1476130718123L),
+              Arrays.asList(1, 2, 3),
+              new StructImpl(Arrays.asList(42, false))
           });
 
       CursorFactory factory = CursorFactory.deduce(columns, null);
@@ -415,6 +442,15 @@ public class AvaticaResultSetConversionsTest {
       }
     }
 
+    public void testGetStruct(ResultSet resultSet) throws SQLException {
+      try {
+        g.getStruct(resultSet);
+        fail("Was expecting to throw SQLDataException");
+      } catch (Exception e) {
+        assertThat(e, isA((Class) SQLDataException.class)); // success
+      }
+    }
+
     public void getURL(ResultSet resultSet) throws SQLException {
       try {
         g.getURL(resultSet);
@@ -507,6 +543,38 @@ public class AvaticaResultSetConversionsTest {
   }
 
   /**
+   * Accessor test helper for array column.
+   */
+  private static final class ArrayAccessorTestHelper extends 
AccessorTestHelper {
+    private ArrayAccessorTestHelper(Getter g) {
+      super(g);
+    }
+
+    @Override public void testGetArray(ResultSet resultSet) throws 
SQLException {
+      ColumnMetaData.ScalarType intType =
+          ColumnMetaData.scalar(Types.INTEGER, "INTEGER", 
ColumnMetaData.Rep.INTEGER);
+      Array expectedArray =
+          new 
ArrayFactoryImpl(Unsafe.localCalendar().getTimeZone()).createArray(
+              intType, Arrays.asList(1, 2, 3));
+      assertTrue(ArrayImpl.equalContents(expectedArray, 
g.getArray(resultSet)));
+    }
+  }
+
+  /**
+   * Accessor test helper for row column.
+   */
+  private static final class StructAccessorTestHelper extends 
AccessorTestHelper {
+    private StructAccessorTestHelper(Getter g) {
+      super(g);
+    }
+
+    @Override public void testGetStruct(ResultSet resultSet) throws 
SQLException {
+      Struct expectedStruct = new StructImpl(Arrays.asList(42, false));
+      assertEquals(expectedStruct, g.getStruct(resultSet));
+    }
+  }
+
+  /**
    * Accessor test helper for the byte column.
    */
   private static final class ByteAccessorTestHelper extends AccessorTestHelper 
{
@@ -937,7 +1005,7 @@ public class AvaticaResultSetConversionsTest {
     }
   }
 
-  @Parameters
+  @Parameters(name = "{index}: {0}")
   public static Collection<AccessorTestHelper> data() {
     return Arrays.asList(
         new BooleanAccessorTestHelper(new OrdinalGetter(1)),
@@ -961,7 +1029,11 @@ public class AvaticaResultSetConversionsTest {
         new TimeAccessorTestHelper(new OrdinalGetter(10)),
         new TimeAccessorTestHelper(new LabelGetter("time")),
         new TimestampAccessorTestHelper(new OrdinalGetter(11)),
-        new TimestampAccessorTestHelper(new LabelGetter("timestamp")));
+        new TimestampAccessorTestHelper(new LabelGetter("timestamp")),
+        new ArrayAccessorTestHelper(new OrdinalGetter(12)),
+        new ArrayAccessorTestHelper(new LabelGetter("array")),
+        new StructAccessorTestHelper(new OrdinalGetter(13)),
+        new StructAccessorTestHelper(new LabelGetter("struct")));
   }
 
   private final AccessorTestHelper testHelper;
@@ -1127,6 +1199,8 @@ public class AvaticaResultSetConversionsTest {
     byte[] getBytes(ResultSet r) throws SQLException;
     InputStream getAsciiStream(ResultSet r) throws SQLException;
     InputStream getBinaryStream(ResultSet r) throws SQLException;
+    Array getArray(ResultSet r) throws SQLException;
+    Struct getStruct(ResultSet r) throws SQLException;
     Object getCharacterStream(ResultSet r) throws SQLException;
     Object getNCharacterStream(ResultSet r) throws SQLException;
     Object getObject(ResultSet r) throws SQLException;
@@ -1137,7 +1211,6 @@ public class AvaticaResultSetConversionsTest {
     Object getNClob(ResultSet r) throws SQLException;
     Object getURL(ResultSet r) throws SQLException;
     Object getSQLXML(ResultSet r) throws SQLException;
-    Object getArray(ResultSet r) throws SQLException;
   }
 
   /** Retrieves the value of a column in a result set, addressing by column
@@ -1266,9 +1339,13 @@ public class AvaticaResultSetConversionsTest {
       return r.getSQLXML(ordinal);
     }
 
-    public Object getArray(ResultSet r) throws SQLException {
+    public Array getArray(ResultSet r) throws SQLException {
       return r.getArray(ordinal);
     }
+
+    public Struct getStruct(ResultSet r) throws SQLException {
+      return (Struct) r.getObject(ordinal);
+    }
   }
 
   /** Retrieves the value of a column in a result set, addressing by column
@@ -1400,6 +1477,10 @@ public class AvaticaResultSetConversionsTest {
     public Array getArray(ResultSet r) throws SQLException {
       return r.getArray(label);
     }
+
+    public Struct getStruct(ResultSet r) throws SQLException {
+      return (Struct) r.getObject(label);
+    }
   }
 }
 

Reply via email to