From 9a12bc661c19f7b7f2ba1c1340fb6c33346697c0 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Sun, 2 Feb 2020 08:54:09 -0700 Subject: [PATCH 01/11] Basic skeleton for JDBC driver --- java/flight/flight-jdbc/README.md | 22 + java/flight/flight-jdbc/pom.xml | 236 ++++ .../org/apache/arrow/jdbc/Connection.java | 319 +++++ .../java/org/apache/arrow/jdbc/Driver.java | 68 ++ .../apache/arrow/jdbc/PreparedStatement.java | 319 +++++ .../java/org/apache/arrow/jdbc/ResultSet.java | 1029 +++++++++++++++++ .../java/org/apache/arrow/jdbc/Statement.java | 273 +++++ java/pom.xml | 1 + 8 files changed, 2267 insertions(+) create mode 100644 java/flight/flight-jdbc/README.md create mode 100644 java/flight/flight-jdbc/pom.xml create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java diff --git a/java/flight/flight-jdbc/README.md b/java/flight/flight-jdbc/README.md new file mode 100644 index 00000000000..2673fbbda27 --- /dev/null +++ b/java/flight/flight-jdbc/README.md @@ -0,0 +1,22 @@ + + +# Apache Arrow Flight JDBC Driver + +JDBC Driver for executing queries against Flight servers. diff --git a/java/flight/flight-jdbc/pom.xml b/java/flight/flight-jdbc/pom.xml new file mode 100644 index 00000000000..3fc1eda128d --- /dev/null +++ b/java/flight/flight-jdbc/pom.xml @@ -0,0 +1,236 @@ + + + + 4.0.0 + + org.apache.arrow + arrow-java-root + 0.16.0-SNAPSHOT + ../../pom.xml + + + flight-jdbc + Arrow Flight JDBC + (Experimental)Flight JDBC Driver + jar + + + 1.24.0 + 3.7.1 + 1 + + + + + org.apache.arrow + flight-core + ${project.version} + + + org.apache.arrow + flight-grpc + ${project.version} + + + + + + + kr.motd.maven + os-maven-plugin + 1.5.0.Final + + + + + maven-surefire-plugin + + false + + ${project.basedir}/../../../testing/data + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.1 + + + shade-main + package + + shade + + + true + shaded + + + io.grpc:* + com.google.protobuf:* + + + + + com.google.protobuf + arrow.flight.com.google.protobuf + + + + + + + + + shade-ext + package + + shade + + + true + shaded-ext + + + io.grpc:* + com.google.protobuf:* + com.google.guava:* + + + + + com.google.protobuf + arrow.flight.com.google.protobuf + + + com.google.common + arrow.flight.com.google.common + + + + + + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.5.0 + + com.google.protobuf:protoc:${dep.protobuf.version}:exe:${os.detected.classifier} + false + grpc-java + io.grpc:protoc-gen-grpc-java:${dep.grpc.version}:exe:${os.detected.classifier} + + + + src + + ${basedir}/../../../format/ + ${project.build.directory}/generated-sources/protobuf + + + compile + compile-custom + + + + test + + ${basedir}/src/test/protobuf + ${project.build.directory}/generated-test-sources//protobuf + + + compile + compile-custom + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + test + + -classpath + + -Xms64m + -Xmx64m + -XX:MaxDirectMemorySize=4g + org.apache.arrow.flight.example.ExampleFlightServer + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + analyze + verify + + analyze-only + + + + io.netty:netty-tcnative-boringssl-static:* + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + add-generated-sources-to-classpath + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/protobuf + + + + + + + maven-assembly-plugin + 3.0.0 + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java new file mode 100644 index 00000000000..8a5983b1d7a --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java @@ -0,0 +1,319 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +/** + * Connection. + */ +public class Connection implements java.sql.Connection { + + protected final String host; + protected final int port; + + public Connection(String host, int port) { + this.host = host; + this.port = port; + } + + @Override + public Statement createStatement() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public PreparedStatement prepareStatement(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public CallableStatement prepareCall(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String nativeSQL(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean getAutoCommit() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setAutoCommit(boolean b) throws SQLException { + + } + + @Override + public void commit() throws SQLException { + + } + + @Override + public void rollback() throws SQLException { + + } + + @Override + public void close() throws SQLException { + + } + + @Override + public boolean isClosed() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isReadOnly() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setReadOnly(boolean b) throws SQLException { + + } + + @Override + public String getCatalog() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setCatalog(String s) throws SQLException { + + } + + @Override + public int getTransactionIsolation() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setTransactionIsolation(int i) throws SQLException { + + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void clearWarnings() throws SQLException { + + } + + @Override + public Statement createStatement(int i, int i1) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public PreparedStatement prepareStatement(String s, int i, int i1) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public CallableStatement prepareCall(String s, int i, int i1) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Map> getTypeMap() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + + } + + @Override + public int getHoldability() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setHoldability(int i) throws SQLException { + + } + + @Override + public Savepoint setSavepoint() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Savepoint setSavepoint(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + + } + + @Override + public Statement createStatement(int i, int i1, int i2) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public PreparedStatement prepareStatement(String s, int i, int i1, int i2) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public CallableStatement prepareCall(String s, int i, int i1, int i2) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public PreparedStatement prepareStatement(String s, int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public PreparedStatement prepareStatement(String s, int[] ints) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public PreparedStatement prepareStatement(String s, String[] strings) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Clob createClob() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Blob createBlob() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public NClob createNClob() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isValid(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setClientInfo(String s, String s1) throws SQLClientInfoException { + + } + + @Override + public String getClientInfo(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Properties getClientInfo() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + + } + + @Override + public Array createArrayOf(String s, Object[] objects) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Struct createStruct(String s, Object[] objects) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getSchema() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setSchema(String s) throws SQLException { + + } + + @Override + public void abort(Executor executor) throws SQLException { + + } + + @Override + public void setNetworkTimeout(Executor executor, int i) throws SQLException { + + } + + @Override + public int getNetworkTimeout() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T unwrap(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isWrapperFor(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java new file mode 100644 index 00000000000..289741a977d --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.sql.Connection; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.Logger; + +/** + * Driver. + */ +public class Driver implements java.sql.Driver { + + private static final String PREFIX = "jdbc:arrow:"; + + @Override + public Connection connect(String s, Properties properties) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + return url != null && url.startsWith(PREFIX); + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String s, Properties properties) throws SQLException { + return new DriverPropertyInfo[0]; + } + + @Override + public int getMajorVersion() { + return 0; + } + + @Override + public int getMinorVersion() { + return 16; + } + + @Override + public boolean jdbcCompliant() { + return false; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java new file mode 100644 index 00000000000..f93b72c948e --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java @@ -0,0 +1,319 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.NClob; +import java.sql.ParameterMetaData; +import java.sql.Ref; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; + +/** + * PreparedStatement. + */ +public class PreparedStatement extends Statement implements java.sql.PreparedStatement { + + @Override + public ResultSet executeQuery() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int executeUpdate() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setNull(int i, int i1) throws SQLException { + + } + + @Override + public void setBoolean(int i, boolean b) throws SQLException { + + } + + @Override + public void setByte(int i, byte b) throws SQLException { + + } + + @Override + public void setShort(int i, short i1) throws SQLException { + + } + + @Override + public void setInt(int i, int i1) throws SQLException { + + } + + @Override + public void setLong(int i, long l) throws SQLException { + + } + + @Override + public void setFloat(int i, float v) throws SQLException { + + } + + @Override + public void setDouble(int i, double v) throws SQLException { + + } + + @Override + public void setBigDecimal(int i, BigDecimal bigDecimal) throws SQLException { + + } + + @Override + public void setString(int i, String s) throws SQLException { + + } + + @Override + public void setBytes(int i, byte[] bytes) throws SQLException { + + } + + @Override + public void setDate(int i, Date date) throws SQLException { + + } + + @Override + public void setTime(int i, Time time) throws SQLException { + + } + + @Override + public void setTimestamp(int i, Timestamp timestamp) throws SQLException { + + } + + @Override + public void setAsciiStream(int i, InputStream inputStream, int i1) throws SQLException { + + } + + @Override + public void setUnicodeStream(int i, InputStream inputStream, int i1) throws SQLException { + + } + + @Override + public void setBinaryStream(int i, InputStream inputStream, int i1) throws SQLException { + + } + + @Override + public void clearParameters() throws SQLException { + + } + + @Override + public void setObject(int i, Object o, int i1) throws SQLException { + + } + + @Override + public void setObject(int i, Object o) throws SQLException { + + } + + @Override + public boolean execute() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void addBatch() throws SQLException { + + } + + @Override + public void setCharacterStream(int i, Reader reader, int i1) throws SQLException { + + } + + @Override + public void setRef(int i, Ref ref) throws SQLException { + + } + + @Override + public void setBlob(int i, Blob blob) throws SQLException { + + } + + @Override + public void setClob(int i, Clob clob) throws SQLException { + + } + + @Override + public void setArray(int i, Array array) throws SQLException { + + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setDate(int i, Date date, Calendar calendar) throws SQLException { + + } + + @Override + public void setTime(int i, Time time, Calendar calendar) throws SQLException { + + } + + @Override + public void setTimestamp(int i, Timestamp timestamp, Calendar calendar) throws SQLException { + + } + + @Override + public void setNull(int i, int i1, String s) throws SQLException { + + } + + @Override + public void setURL(int i, URL url) throws SQLException { + + } + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setRowId(int i, RowId rowId) throws SQLException { + + } + + @Override + public void setNString(int i, String s) throws SQLException { + + } + + @Override + public void setNCharacterStream(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void setNClob(int i, NClob nClob) throws SQLException { + + } + + @Override + public void setClob(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void setBlob(int i, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void setNClob(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void setSQLXML(int i, SQLXML sqlxml) throws SQLException { + + } + + @Override + public void setObject(int i, Object o, int i1, int i2) throws SQLException { + + } + + @Override + public void setAsciiStream(int i, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void setBinaryStream(int i, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void setCharacterStream(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void setAsciiStream(int i, InputStream inputStream) throws SQLException { + + } + + @Override + public void setBinaryStream(int i, InputStream inputStream) throws SQLException { + + } + + @Override + public void setCharacterStream(int i, Reader reader) throws SQLException { + + } + + @Override + public void setNCharacterStream(int i, Reader reader) throws SQLException { + + } + + @Override + public void setClob(int i, Reader reader) throws SQLException { + + } + + @Override + public void setBlob(int i, InputStream inputStream) throws SQLException { + + } + + @Override + public void setNClob(int i, Reader reader) throws SQLException { + + } +} diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java new file mode 100644 index 00000000000..4702f73a22b --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java @@ -0,0 +1,1029 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.NClob; +import java.sql.Ref; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; + +import org.apache.arrow.flight.FlightStream; + +/** + * ResultSet. + */ +public class ResultSet implements java.sql.ResultSet { + + /** + * Stream of RecordBatch. + */ + private final FlightStream stream; + + private boolean wasNull; + + public ResultSet(FlightStream stream) { + this.stream = stream; + } + + @Override + public boolean next() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(int i) throws SQLException { + //TODO implement + this.wasNull = false; + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getString(int i) throws SQLException { + return String.valueOf(getObject(i)); + } + + @Override + public boolean getBoolean(int i) throws SQLException { + final Object value = getObject(i); + if (value == null) { + throw new SQLFeatureNotSupportedException(); + } else if (value instanceof Boolean) { + return (Boolean) value; + } else if (value instanceof String) { + return ((String) value).equalsIgnoreCase("true"); + } else { + throw new SQLException(); + } + } + + @Override + public boolean wasNull() throws SQLException { + return wasNull; + } + + @Override + public void close() throws SQLException { + try { + stream.close(); + } catch (Exception e) { + throw new SQLException(e); + } + } + + @Override + public byte getByte(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public short getShort(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getInt(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public long getLong(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public float getFloat(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public double getDouble(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public BigDecimal getBigDecimal(int i, int i1) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public byte[] getBytes(int i) throws SQLException { + return new byte[0]; + } + + @Override + public Date getDate(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getAsciiStream(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getUnicodeStream(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getBinaryStream(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getString(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean getBoolean(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public byte getByte(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public short getShort(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getInt(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public long getLong(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public float getFloat(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public double getDouble(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public BigDecimal getBigDecimal(String s, int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public byte[] getBytes(String s) throws SQLException { + return new byte[0]; + } + + @Override + public Date getDate(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getAsciiStream(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getUnicodeStream(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getBinaryStream(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void clearWarnings() throws SQLException { + + } + + @Override + public String getCursorName() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int findColumn(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getCharacterStream(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getCharacterStream(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public BigDecimal getBigDecimal(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public BigDecimal getBigDecimal(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isBeforeFirst() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isAfterLast() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isFirst() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isLast() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void beforeFirst() throws SQLException { + + } + + @Override + public void afterLast() throws SQLException { + + } + + @Override + public boolean first() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean last() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getRow() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean absolute(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean relative(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean previous() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getFetchDirection() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setFetchDirection(int i) throws SQLException { + + } + + @Override + public int getFetchSize() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setFetchSize(int i) throws SQLException { + + } + + @Override + public int getType() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getConcurrency() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean rowUpdated() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean rowInserted() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean rowDeleted() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNull(int i) throws SQLException { + + } + + @Override + public void updateBoolean(int i, boolean b) throws SQLException { + + } + + @Override + public void updateByte(int i, byte b) throws SQLException { + + } + + @Override + public void updateShort(int i, short i1) throws SQLException { + + } + + @Override + public void updateInt(int i, int i1) throws SQLException { + + } + + @Override + public void updateLong(int i, long l) throws SQLException { + + } + + @Override + public void updateFloat(int i, float v) throws SQLException { + + } + + @Override + public void updateDouble(int i, double v) throws SQLException { + + } + + @Override + public void updateBigDecimal(int i, BigDecimal bigDecimal) throws SQLException { + + } + + @Override + public void updateString(int i, String s) throws SQLException { + + } + + @Override + public void updateBytes(int i, byte[] bytes) throws SQLException { + + } + + @Override + public void updateDate(int i, Date date) throws SQLException { + + } + + @Override + public void updateTime(int i, Time time) throws SQLException { + + } + + @Override + public void updateTimestamp(int i, Timestamp timestamp) throws SQLException { + + } + + @Override + public void updateAsciiStream(int i, InputStream inputStream, int i1) throws SQLException { + + } + + @Override + public void updateBinaryStream(int i, InputStream inputStream, int i1) throws SQLException { + + } + + @Override + public void updateCharacterStream(int i, Reader reader, int i1) throws SQLException { + + } + + @Override + public void updateObject(int i, Object o, int i1) throws SQLException { + + } + + @Override + public void updateObject(int i, Object o) throws SQLException { + + } + + @Override + public void updateNull(String s) throws SQLException { + + } + + @Override + public void updateBoolean(String s, boolean b) throws SQLException { + + } + + @Override + public void updateByte(String s, byte b) throws SQLException { + + } + + @Override + public void updateShort(String s, short i) throws SQLException { + + } + + @Override + public void updateInt(String s, int i) throws SQLException { + + } + + @Override + public void updateLong(String s, long l) throws SQLException { + + } + + @Override + public void updateFloat(String s, float v) throws SQLException { + + } + + @Override + public void updateDouble(String s, double v) throws SQLException { + + } + + @Override + public void updateBigDecimal(String s, BigDecimal bigDecimal) throws SQLException { + + } + + @Override + public void updateString(String s, String s1) throws SQLException { + + } + + @Override + public void updateBytes(String s, byte[] bytes) throws SQLException { + + } + + @Override + public void updateDate(String s, Date date) throws SQLException { + + } + + @Override + public void updateTime(String s, Time time) throws SQLException { + + } + + @Override + public void updateTimestamp(String s, Timestamp timestamp) throws SQLException { + + } + + @Override + public void updateAsciiStream(String s, InputStream inputStream, int i) throws SQLException { + + } + + @Override + public void updateBinaryStream(String s, InputStream inputStream, int i) throws SQLException { + + } + + @Override + public void updateCharacterStream(String s, Reader reader, int i) throws SQLException { + + } + + @Override + public void updateObject(String s, Object o, int i) throws SQLException { + + } + + @Override + public void updateObject(String s, Object o) throws SQLException { + + } + + @Override + public void insertRow() throws SQLException { + + } + + @Override + public void updateRow() throws SQLException { + + } + + @Override + public void deleteRow() throws SQLException { + + } + + @Override + public void refreshRow() throws SQLException { + + } + + @Override + public void cancelRowUpdates() throws SQLException { + + } + + @Override + public void moveToInsertRow() throws SQLException { + + } + + @Override + public void moveToCurrentRow() throws SQLException { + + } + + @Override + public Statement getStatement() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(int i, Map> map) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Ref getRef(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Blob getBlob(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Clob getClob(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Array getArray(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(String s, Map> map) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Ref getRef(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Blob getBlob(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Clob getClob(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Array getArray(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Date getDate(int i, Calendar calendar) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Date getDate(String s, Calendar calendar) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(int i, Calendar calendar) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(String s, Calendar calendar) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(int i, Calendar calendar) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(String s, Calendar calendar) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public URL getURL(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public URL getURL(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateRef(int i, Ref ref) throws SQLException { + + } + + @Override + public void updateRef(String s, Ref ref) throws SQLException { + + } + + @Override + public void updateBlob(int i, Blob blob) throws SQLException { + + } + + @Override + public void updateBlob(String s, Blob blob) throws SQLException { + + } + + @Override + public void updateClob(int i, Clob clob) throws SQLException { + + } + + @Override + public void updateClob(String s, Clob clob) throws SQLException { + + } + + @Override + public void updateArray(int i, Array array) throws SQLException { + + } + + @Override + public void updateArray(String s, Array array) throws SQLException { + + } + + @Override + public RowId getRowId(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public RowId getRowId(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateRowId(int i, RowId rowId) throws SQLException { + + } + + @Override + public void updateRowId(String s, RowId rowId) throws SQLException { + + } + + @Override + public int getHoldability() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isClosed() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNString(int i, String s) throws SQLException { + + } + + @Override + public void updateNString(String s, String s1) throws SQLException { + + } + + @Override + public void updateNClob(int i, NClob nClob) throws SQLException { + + } + + @Override + public void updateNClob(String s, NClob nClob) throws SQLException { + + } + + @Override + public NClob getNClob(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public NClob getNClob(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public SQLXML getSQLXML(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public SQLXML getSQLXML(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateSQLXML(int i, SQLXML sqlxml) throws SQLException { + + } + + @Override + public void updateSQLXML(String s, SQLXML sqlxml) throws SQLException { + + } + + @Override + public String getNString(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getNString(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getNCharacterStream(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getNCharacterStream(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNCharacterStream(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateNCharacterStream(String s, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateAsciiStream(int i, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void updateBinaryStream(int i, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void updateCharacterStream(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateAsciiStream(String s, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void updateBinaryStream(String s, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void updateCharacterStream(String s, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateBlob(int i, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void updateBlob(String s, InputStream inputStream, long l) throws SQLException { + + } + + @Override + public void updateClob(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateClob(String s, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateNClob(int i, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateNClob(String s, Reader reader, long l) throws SQLException { + + } + + @Override + public void updateNCharacterStream(int i, Reader reader) throws SQLException { + + } + + @Override + public void updateNCharacterStream(String s, Reader reader) throws SQLException { + + } + + @Override + public void updateAsciiStream(int i, InputStream inputStream) throws SQLException { + + } + + @Override + public void updateBinaryStream(int i, InputStream inputStream) throws SQLException { + + } + + @Override + public void updateCharacterStream(int i, Reader reader) throws SQLException { + + } + + @Override + public void updateAsciiStream(String s, InputStream inputStream) throws SQLException { + + } + + @Override + public void updateBinaryStream(String s, InputStream inputStream) throws SQLException { + + } + + @Override + public void updateCharacterStream(String s, Reader reader) throws SQLException { + + } + + @Override + public void updateBlob(int i, InputStream inputStream) throws SQLException { + + } + + @Override + public void updateBlob(String s, InputStream inputStream) throws SQLException { + + } + + @Override + public void updateClob(int i, Reader reader) throws SQLException { + + } + + @Override + public void updateClob(String s, Reader reader) throws SQLException { + + } + + @Override + public void updateNClob(int i, Reader reader) throws SQLException { + + } + + @Override + public void updateNClob(String s, Reader reader) throws SQLException { + + } + + @Override + public T getObject(int i, Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T getObject(String s, Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T unwrap(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isWrapperFor(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java new file mode 100644 index 00000000000..fe5583fcf8b --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java @@ -0,0 +1,273 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLWarning; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.flight.CallOption; +import org.apache.arrow.flight.CallOptions; +import org.apache.arrow.flight.FlightClient; +import org.apache.arrow.flight.FlightStream; +import org.apache.arrow.flight.Location; +import org.apache.arrow.flight.Ticket; +import org.apache.arrow.memory.RootAllocator; + +/** + * Statement. + */ +public class Statement implements java.sql.Statement { + + private org.apache.arrow.jdbc.Connection connection; + + @Override + public ResultSet executeQuery(String query) throws SQLException { + + FlightClient client = FlightClient.builder() + .allocator(new RootAllocator(Long.MAX_VALUE)) + .location(Location.forGrpcInsecure(connection.host, connection.port)) + .build(); + + CallOption callOptions = CallOptions.timeout(5, TimeUnit.SECONDS); + + Ticket ticket = new Ticket(query.getBytes()); + + FlightStream stream = client.getStream(ticket, callOptions); + + return new org.apache.arrow.jdbc.ResultSet(stream); + } + + @Override + public int executeUpdate(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void close() throws SQLException { + + } + + @Override + public int getMaxFieldSize() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setMaxFieldSize(int i) throws SQLException { + + } + + @Override + public int getMaxRows() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setMaxRows(int i) throws SQLException { + + } + + @Override + public void setEscapeProcessing(boolean b) throws SQLException { + + } + + @Override + public int getQueryTimeout() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setQueryTimeout(int i) throws SQLException { + + } + + @Override + public void cancel() throws SQLException { + + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void clearWarnings() throws SQLException { + + } + + @Override + public void setCursorName(String s) throws SQLException { + + } + + @Override + public boolean execute(String s) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSet getResultSet() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getUpdateCount() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean getMoreResults() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getFetchDirection() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setFetchDirection(int i) throws SQLException { + + } + + @Override + public int getFetchSize() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setFetchSize(int i) throws SQLException { + + } + + @Override + public int getResultSetConcurrency() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getResultSetType() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void addBatch(String s) throws SQLException { + + } + + @Override + public void clearBatch() throws SQLException { + + } + + @Override + public int[] executeBatch() throws SQLException { + return new int[0]; + } + + @Override + public Connection getConnection() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean getMoreResults(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int executeUpdate(String s, int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int executeUpdate(String s, int[] ints) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int executeUpdate(String s, String[] strings) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean execute(String s, int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean execute(String s, int[] ints) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean execute(String s, String[] strings) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getResultSetHoldability() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isClosed() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isPoolable() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setPoolable(boolean b) throws SQLException { + + } + + @Override + public void closeOnCompletion() throws SQLException { + + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T unwrap(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isWrapperFor(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/java/pom.xml b/java/pom.xml index 8397ef29e7d..dc162768fcb 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -682,6 +682,7 @@ plasma flight/flight-core flight/flight-grpc + flight/flight-jdbc performance algorithm adapter/avro From acbaf12576c660e57deb1a22db4d659ca5574b6b Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Sun, 2 Feb 2020 09:02:55 -0700 Subject: [PATCH 02/11] add unit test --- java/flight/flight-jdbc/pom.xml | 17 ------- .../java/org/apache/arrow/jdbc/Driver.java | 3 +- .../org/apache/arrow/jdbc/DriverTest.java | 48 +++++++++++++++++++ 3 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java diff --git a/java/flight/flight-jdbc/pom.xml b/java/flight/flight-jdbc/pom.xml index 3fc1eda128d..e77c0b1e291 100644 --- a/java/flight/flight-jdbc/pom.xml +++ b/java/flight/flight-jdbc/pom.xml @@ -159,23 +159,6 @@ - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - java - test - - -classpath - - -Xms64m - -Xmx64m - -XX:MaxDirectMemorySize=4g - org.apache.arrow.flight.example.ExampleFlightServer - - - org.apache.maven.plugins maven-dependency-plugin diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java index 289741a977d..bff22663207 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java @@ -32,7 +32,8 @@ public class Driver implements java.sql.Driver { private static final String PREFIX = "jdbc:arrow:"; @Override - public Connection connect(String s, Properties properties) throws SQLException { + public Connection connect(String url, Properties properties) throws SQLException { + throw new SQLFeatureNotSupportedException(); } diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java new file mode 100644 index 00000000000..e14eacc5972 --- /dev/null +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.sql.SQLException; + +import org.junit.Test; + +/** + * JDBC Driver unit tests. + */ +public class DriverTest { + + final Driver driver = new org.apache.arrow.jdbc.Driver(); + + @Test + public void acceptsValidUrl() throws SQLException { + assertTrue(driver.acceptsURL("jdbc:arrow://localhost:50051")); + } + + @Test + public void rejectsInvalidUrl() throws SQLException { + assertFalse(driver.acceptsURL("jdbc:mysql://localhost:50051")); + } + + @Test + public void rejectsNullUrl() throws SQLException { + assertFalse(driver.acceptsURL(null)); + } +} From f15f31a5c31c9fff59906782109726809b1fd2bd Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Sun, 2 Feb 2020 09:22:34 -0700 Subject: [PATCH 03/11] test executing query and fetching one row --- .../org/apache/arrow/jdbc/Connection.java | 2 +- .../java/org/apache/arrow/jdbc/Driver.java | 18 ++++++++++++---- .../java/org/apache/arrow/jdbc/ResultSet.java | 21 ++++++++++++++----- .../java/org/apache/arrow/jdbc/Statement.java | 6 +++++- .../org/apache/arrow/jdbc/DriverTest.java | 19 +++++++++++++++-- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java index 8a5983b1d7a..c8bd7652011 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java @@ -49,7 +49,7 @@ public Connection(String host, int port) { @Override public Statement createStatement() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return new Statement(this); } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java index bff22663207..5ed607e4fe2 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java @@ -17,24 +17,34 @@ package org.apache.arrow.jdbc; -import java.sql.Connection; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import java.util.logging.Logger; +import org.slf4j.LoggerFactory; + /** * Driver. */ public class Driver implements java.sql.Driver { - private static final String PREFIX = "jdbc:arrow:"; + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Driver.class); + + private static final String PREFIX = "jdbc:arrow://"; @Override public Connection connect(String url, Properties properties) throws SQLException { - - throw new SQLFeatureNotSupportedException(); + logger.info("connect() url={}", url); + //TODO this needs much more work to parse full URLs but this is enough to get end to end tests running + String c = url.substring(PREFIX.length()); + int i = c.indexOf(':'); + if (i == -1) { + return new Connection(c, 50051); + } else { + return new Connection(c.substring(0,i), Integer.parseInt(c.substring(i + 1))); + } } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java index 4702f73a22b..14f2291c240 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java @@ -40,6 +40,7 @@ import java.util.Map; import org.apache.arrow.flight.FlightStream; +import org.apache.arrow.vector.VectorSchemaRoot; /** * ResultSet. @@ -51,22 +52,32 @@ public class ResultSet implements java.sql.ResultSet { */ private final FlightStream stream; + private VectorSchemaRoot root; + private boolean wasNull; - public ResultSet(FlightStream stream) { + /** + * Create a ResultSet to wrap a FlightStream. + */ + public ResultSet(final FlightStream stream) { this.stream = stream; + + if (stream.next()) { + this.root = stream.getRoot(); + } } @Override public boolean next() throws SQLException { - throw new SQLFeatureNotSupportedException(); + //TODO + return true; } @Override public Object getObject(int i) throws SQLException { - //TODO implement - this.wasNull = false; - throw new SQLFeatureNotSupportedException(); + final Object value = this.root.getFieldVectors().get(i - 1).getObject(i); + this.wasNull = value == null; + return value; } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java index fe5583fcf8b..70d706c7a4b 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java @@ -37,7 +37,11 @@ */ public class Statement implements java.sql.Statement { - private org.apache.arrow.jdbc.Connection connection; + protected final org.apache.arrow.jdbc.Connection connection; + + public Statement(org.apache.arrow.jdbc.Connection connection) { + this.connection = connection; + } @Override public ResultSet executeQuery(String query) throws SQLException { diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index e14eacc5972..f6ab8bfa6ce 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -17,10 +17,13 @@ package org.apache.arrow.jdbc; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; +import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; import org.junit.Test; @@ -45,4 +48,16 @@ public void rejectsInvalidUrl() throws SQLException { public void rejectsNullUrl() throws SQLException { assertFalse(driver.acceptsURL(null)); } + + @Test + public void executeQuery() throws SQLException { + try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { + try (Statement stmt = conn.createStatement()) { + try (ResultSet rs = stmt.executeQuery("SELECT id FROM alltypes_plain")) { + assertTrue(rs.next()); + assertEquals(1, rs.getInt(1)); + } + } + } + } } From 3c70a5b2d70bf720815cc6a5baccc834ea23e792 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Sun, 2 Feb 2020 09:47:40 -0700 Subject: [PATCH 04/11] rename classes to use Flight prefix to simplify imports --- .../java/org/apache/arrow/jdbc/Driver.java | 6 +++-- ...{Connection.java => FlightConnection.java} | 24 +++++++++---------- ...ment.java => FlightPreparedStatement.java} | 8 +++++-- .../{ResultSet.java => FlightResultSet.java} | 4 ++-- .../{Statement.java => FlightStatement.java} | 12 +++++----- .../org/apache/arrow/jdbc/DriverTest.java | 2 ++ 6 files changed, 32 insertions(+), 24 deletions(-) rename java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/{Connection.java => FlightConnection.java} (87%) rename java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/{PreparedStatement.java => FlightPreparedStatement.java} (96%) rename java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/{ResultSet.java => FlightResultSet.java} (99%) rename java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/{Statement.java => FlightStatement.java} (94%) diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java index 5ed607e4fe2..73d499d0d60 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Driver.java @@ -17,6 +17,7 @@ package org.apache.arrow.jdbc; +import java.sql.Connection; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; @@ -32,6 +33,7 @@ public class Driver implements java.sql.Driver { private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Driver.class); + /** JDBC connection string prefix. */ private static final String PREFIX = "jdbc:arrow://"; @Override @@ -41,9 +43,9 @@ public Connection connect(String url, Properties properties) throws SQLException String c = url.substring(PREFIX.length()); int i = c.indexOf(':'); if (i == -1) { - return new Connection(c, 50051); + return new FlightConnection(c, 50051); } else { - return new Connection(c.substring(0,i), Integer.parseInt(c.substring(i + 1))); + return new FlightConnection(c.substring(0,i), Integer.parseInt(c.substring(i + 1))); } } diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java similarity index 87% rename from java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java rename to java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java index c8bd7652011..d59234421c1 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Connection.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java @@ -37,23 +37,23 @@ /** * Connection. */ -public class Connection implements java.sql.Connection { +public class FlightConnection implements java.sql.Connection { protected final String host; protected final int port; - public Connection(String host, int port) { + public FlightConnection(String host, int port) { this.host = host; this.port = port; } @Override - public Statement createStatement() throws SQLException { - return new Statement(this); + public FlightStatement createStatement() throws SQLException { + return new FlightStatement(this); } @Override - public PreparedStatement prepareStatement(String s) throws SQLException { + public FlightPreparedStatement prepareStatement(String s) throws SQLException { throw new SQLFeatureNotSupportedException(); } @@ -143,12 +143,12 @@ public void clearWarnings() throws SQLException { } @Override - public Statement createStatement(int i, int i1) throws SQLException { + public FlightStatement createStatement(int i, int i1) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public PreparedStatement prepareStatement(String s, int i, int i1) throws SQLException { + public FlightPreparedStatement prepareStatement(String s, int i, int i1) throws SQLException { throw new SQLFeatureNotSupportedException(); } @@ -198,12 +198,12 @@ public void releaseSavepoint(Savepoint savepoint) throws SQLException { } @Override - public Statement createStatement(int i, int i1, int i2) throws SQLException { + public FlightStatement createStatement(int i, int i1, int i2) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public PreparedStatement prepareStatement(String s, int i, int i1, int i2) throws SQLException { + public FlightPreparedStatement prepareStatement(String s, int i, int i1, int i2) throws SQLException { throw new SQLFeatureNotSupportedException(); } @@ -213,17 +213,17 @@ public CallableStatement prepareCall(String s, int i, int i1, int i2) throws SQL } @Override - public PreparedStatement prepareStatement(String s, int i) throws SQLException { + public FlightPreparedStatement prepareStatement(String s, int i) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public PreparedStatement prepareStatement(String s, int[] ints) throws SQLException { + public FlightPreparedStatement prepareStatement(String s, int[] ints) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public PreparedStatement prepareStatement(String s, String[] strings) throws SQLException { + public FlightPreparedStatement prepareStatement(String s, String[] strings) throws SQLException { throw new SQLFeatureNotSupportedException(); } diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java similarity index 96% rename from java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java rename to java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java index f93b72c948e..67cc74e3aaf 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/PreparedStatement.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java @@ -40,10 +40,14 @@ /** * PreparedStatement. */ -public class PreparedStatement extends Statement implements java.sql.PreparedStatement { +public class FlightPreparedStatement extends FlightStatement implements java.sql.PreparedStatement { + + public FlightPreparedStatement(FlightConnection flightConnection) { + super(flightConnection); + } @Override - public ResultSet executeQuery() throws SQLException { + public FlightResultSet executeQuery() throws SQLException { throw new SQLFeatureNotSupportedException(); } diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java similarity index 99% rename from java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java rename to java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java index 14f2291c240..84f84bab4ce 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSet.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java @@ -45,7 +45,7 @@ /** * ResultSet. */ -public class ResultSet implements java.sql.ResultSet { +public class FlightResultSet implements java.sql.ResultSet { /** * Stream of RecordBatch. @@ -59,7 +59,7 @@ public class ResultSet implements java.sql.ResultSet { /** * Create a ResultSet to wrap a FlightStream. */ - public ResultSet(final FlightStream stream) { + public FlightResultSet(final FlightStream stream) { this.stream = stream; if (stream.next()) { diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java similarity index 94% rename from java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java rename to java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java index 70d706c7a4b..7e81d2e49b1 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/Statement.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java @@ -35,12 +35,12 @@ /** * Statement. */ -public class Statement implements java.sql.Statement { +public class FlightStatement implements java.sql.Statement { - protected final org.apache.arrow.jdbc.Connection connection; + protected final FlightConnection flightConnection; - public Statement(org.apache.arrow.jdbc.Connection connection) { - this.connection = connection; + public FlightStatement(FlightConnection flightConnection) { + this.flightConnection = flightConnection; } @Override @@ -48,7 +48,7 @@ public ResultSet executeQuery(String query) throws SQLException { FlightClient client = FlightClient.builder() .allocator(new RootAllocator(Long.MAX_VALUE)) - .location(Location.forGrpcInsecure(connection.host, connection.port)) + .location(Location.forGrpcInsecure(flightConnection.host, flightConnection.port)) .build(); CallOption callOptions = CallOptions.timeout(5, TimeUnit.SECONDS); @@ -57,7 +57,7 @@ public ResultSet executeQuery(String query) throws SQLException { FlightStream stream = client.getStream(ticket, callOptions); - return new org.apache.arrow.jdbc.ResultSet(stream); + return new FlightResultSet(stream); } @Override diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index f6ab8bfa6ce..8f416f10318 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -25,6 +25,7 @@ import java.sql.Statement; import java.util.Properties; +import org.junit.Ignore; import org.junit.Test; /** @@ -49,6 +50,7 @@ public void rejectsNullUrl() throws SQLException { assertFalse(driver.acceptsURL(null)); } + @Ignore @Test public void executeQuery() throws SQLException { try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { From d91884f5c6244a517daa49628ff5bef2c2f39e5d Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Sun, 2 Feb 2020 10:13:18 -0700 Subject: [PATCH 05/11] move type conversion code to helper class for easier unit testing --- .../apache/arrow/jdbc/FlightResultSet.java | 81 ++++++-------- .../apache/arrow/jdbc/ResultSetHelper.java | 105 ++++++++++++++++++ .../arrow/jdbc/ResultSetHelperTest.java | 40 +++++++ 3 files changed, 181 insertions(+), 45 deletions(-) create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java create mode 100644 java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java index 84f84bab4ce..7573ab88106 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java @@ -82,21 +82,12 @@ public Object getObject(int i) throws SQLException { @Override public String getString(int i) throws SQLException { - return String.valueOf(getObject(i)); + return ResultSetHelper.getString(getObject(i)); } @Override public boolean getBoolean(int i) throws SQLException { - final Object value = getObject(i); - if (value == null) { - throw new SQLFeatureNotSupportedException(); - } else if (value instanceof Boolean) { - return (Boolean) value; - } else if (value instanceof String) { - return ((String) value).equalsIgnoreCase("true"); - } else { - throw new SQLException(); - } + return ResultSetHelper.getBoolean(getObject(i)); } @Override @@ -115,32 +106,32 @@ public void close() throws SQLException { @Override public byte getByte(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getByte(getObject(i)); } @Override public short getShort(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getShort(getObject(i)); } @Override public int getInt(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getInt(getObject(i)); } @Override public long getLong(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getLong(getObject(i)); } @Override public float getFloat(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getFloat(getObject(i)); } @Override public double getDouble(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getDouble(getObject(i)); } @Override @@ -150,22 +141,22 @@ public BigDecimal getBigDecimal(int i, int i1) throws SQLException { @Override public byte[] getBytes(int i) throws SQLException { - return new byte[0]; + return ResultSetHelper.getBytes(getObject(i)); } @Override public Date getDate(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getDate(getObject(i)); } @Override public Time getTime(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getTime(getObject(i)); } @Override public Timestamp getTimestamp(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getTimestamp(getObject(i)); } @Override @@ -184,57 +175,57 @@ public InputStream getBinaryStream(int i) throws SQLException { } @Override - public String getString(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public String getString(String columnName) throws SQLException { + return ResultSetHelper.getString(getObject(columnName)); } @Override - public boolean getBoolean(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public boolean getBoolean(String columnName) throws SQLException { + return ResultSetHelper.getBoolean(getObject(columnName)); } @Override - public byte getByte(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public byte getByte(String columnName) throws SQLException { + return ResultSetHelper.getByte(getObject(columnName)); } @Override - public short getShort(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public short getShort(String columnName) throws SQLException { + return ResultSetHelper.getShort(getObject(columnName)); } @Override - public int getInt(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public int getInt(String columnName) throws SQLException { + return ResultSetHelper.getInt(getObject(columnName)); } @Override - public long getLong(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public long getLong(String columnName) throws SQLException { + return ResultSetHelper.getLong(getObject(columnName)); } @Override - public float getFloat(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public float getFloat(String columnName) throws SQLException { + return ResultSetHelper.getFloat(getObject(columnName)); } @Override - public double getDouble(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public double getDouble(String columnName) throws SQLException { + return ResultSetHelper.getDouble(getObject(columnName)); } @Override - public BigDecimal getBigDecimal(String s, int i) throws SQLException { + public BigDecimal getBigDecimal(String columnName, int i) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public byte[] getBytes(String s) throws SQLException { - return new byte[0]; + public byte[] getBytes(String columnName) throws SQLException { + return ResultSetHelper.getBytes(getObject(columnName)); } @Override - public Date getDate(String s) throws SQLException { + public Date getDate(String columnName) throws SQLException { throw new SQLFeatureNotSupportedException(); } @@ -244,22 +235,22 @@ public Time getTime(String s) throws SQLException { } @Override - public Timestamp getTimestamp(String s) throws SQLException { + public Timestamp getTimestamp(String columnName) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public InputStream getAsciiStream(String s) throws SQLException { + public InputStream getAsciiStream(String columnName) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public InputStream getUnicodeStream(String s) throws SQLException { + public InputStream getUnicodeStream(String columnName) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override - public InputStream getBinaryStream(String s) throws SQLException { + public InputStream getBinaryStream(String columnName) throws SQLException { throw new SQLFeatureNotSupportedException(); } diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java new file mode 100644 index 00000000000..3c11f800d80 --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Time; +import java.sql.Timestamp; + +/** + * Helper methods for converting between data types. + */ +public class ResultSetHelper { + + /** Convert value to String. */ + public static String getString(final Object value) throws SQLException { + return String.valueOf(value); + } + + /** Convert value to boolean. */ + public static boolean getBoolean(final Object value) throws SQLException { + if (value == null) { + return false; + } else if (value instanceof Boolean) { + return (Boolean) value; + } else if (value instanceof String) { + return ((String) value).equalsIgnoreCase("true"); + } else { + throw new SQLException(); + } + } + + /** Convert value to byte. */ + public static byte getByte(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to short. */ + public static short getShort(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to int. */ + public static int getInt(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to String. */ + public static long getLong(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to float. */ + public static float getFloat(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to double. */ + public static double getDouble(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to BigDecimal. */ + public static BigDecimal getBigDecimal(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to byte[]. */ + public static byte[] getBytes(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to Date. */ + public static Date getDate(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to Time. */ + public static Time getTime(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + /** Convert value to Timestamp. */ + public static Timestamp getTimestamp(final Object value) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + +} diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java new file mode 100644 index 00000000000..c2842746a62 --- /dev/null +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import static org.junit.Assert.*; + +import java.sql.SQLException; + +import org.junit.Test; + +/** + * JDBC Driver unit tests. + */ +public class ResultSetHelperTest { + + //TODO add exhaustive tests based on suggested conversions in JDBC specification + + @Test + public void testString() throws SQLException { + assertEquals(null, ResultSetHelper.getString(null)); + assertEquals("a", ResultSetHelper.getString("a")); + assertEquals("123", ResultSetHelper.getString(123)); + } + +} From fbd954980a3f31c2ded68aeac6b21bcdc4fcc9e6 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Mon, 3 Feb 2020 08:16:31 -0700 Subject: [PATCH 06/11] make most methods throw SQLFeatureNotSupportedException --- .../apache/arrow/jdbc/FlightConnection.java | 31 +-- .../arrow/jdbc/FlightPreparedStatement.java | 100 +++++----- .../apache/arrow/jdbc/FlightResultSet.java | 187 +++++++++--------- .../apache/arrow/jdbc/FlightStatement.java | 26 ++- .../apache/arrow/jdbc/ResultSetHelper.java | 2 +- .../arrow/jdbc/ResultSetHelperTest.java | 2 +- 6 files changed, 173 insertions(+), 175 deletions(-) diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java index d59234421c1..27735fbae21 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightConnection.java @@ -74,17 +74,17 @@ public boolean getAutoCommit() throws SQLException { @Override public void setAutoCommit(boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void commit() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void rollback() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -109,7 +109,7 @@ public boolean isReadOnly() throws SQLException { @Override public void setReadOnly(boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -119,7 +119,7 @@ public String getCatalog() throws SQLException { @Override public void setCatalog(String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -129,7 +129,7 @@ public int getTransactionIsolation() throws SQLException { @Override public void setTransactionIsolation(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -139,7 +139,7 @@ public SQLWarning getWarnings() throws SQLException { @Override public void clearWarnings() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -164,7 +164,7 @@ public Map> getTypeMap() throws SQLException { @Override public void setTypeMap(Map> map) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -174,7 +174,7 @@ public int getHoldability() throws SQLException { @Override public void setHoldability(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -189,12 +189,12 @@ public Savepoint setSavepoint(String s) throws SQLException { @Override public void rollback(Savepoint savepoint) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -254,6 +254,7 @@ public boolean isValid(int i) throws SQLException { @Override public void setClientInfo(String s, String s1) throws SQLClientInfoException { + throw new SQLClientInfoException(); } @@ -269,7 +270,7 @@ public Properties getClientInfo() throws SQLException { @Override public void setClientInfo(Properties properties) throws SQLClientInfoException { - + throw new SQLClientInfoException(); } @Override @@ -289,17 +290,17 @@ public String getSchema() throws SQLException { @Override public void setSchema(String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void abort(Executor executor) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNetworkTimeout(Executor executor, int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java index 67cc74e3aaf..5ebe2f19d7c 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightPreparedStatement.java @@ -58,102 +58,102 @@ public int executeUpdate() throws SQLException { @Override public void setNull(int i, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBoolean(int i, boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setByte(int i, byte b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setShort(int i, short i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setInt(int i, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setLong(int i, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setFloat(int i, float v) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setDouble(int i, double v) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBigDecimal(int i, BigDecimal bigDecimal) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setString(int i, String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBytes(int i, byte[] bytes) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setDate(int i, Date date) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setTime(int i, Time time) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setTimestamp(int i, Timestamp timestamp) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setAsciiStream(int i, InputStream inputStream, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setUnicodeStream(int i, InputStream inputStream, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBinaryStream(int i, InputStream inputStream, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void clearParameters() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setObject(int i, Object o, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setObject(int i, Object o) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -163,32 +163,32 @@ public boolean execute() throws SQLException { @Override public void addBatch() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setCharacterStream(int i, Reader reader, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setRef(int i, Ref ref) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBlob(int i, Blob blob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setClob(int i, Clob clob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setArray(int i, Array array) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -198,27 +198,27 @@ public ResultSetMetaData getMetaData() throws SQLException { @Override public void setDate(int i, Date date, Calendar calendar) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setTime(int i, Time time, Calendar calendar) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setTimestamp(int i, Timestamp timestamp, Calendar calendar) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNull(int i, int i1, String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setURL(int i, URL url) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -228,96 +228,96 @@ public ParameterMetaData getParameterMetaData() throws SQLException { @Override public void setRowId(int i, RowId rowId) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNString(int i, String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNCharacterStream(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNClob(int i, NClob nClob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setClob(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBlob(int i, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNClob(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setSQLXML(int i, SQLXML sqlxml) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setObject(int i, Object o, int i1, int i2) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setAsciiStream(int i, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBinaryStream(int i, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setCharacterStream(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setAsciiStream(int i, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBinaryStream(int i, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setCharacterStream(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNCharacterStream(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setClob(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setBlob(int i, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setNClob(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } } diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java index 7573ab88106..b97d978cc94 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java @@ -261,7 +261,6 @@ public SQLWarning getWarnings() throws SQLException { @Override public void clearWarnings() throws SQLException { - } @Override @@ -326,12 +325,12 @@ public boolean isLast() throws SQLException { @Override public void beforeFirst() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void afterLast() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -371,7 +370,7 @@ public int getFetchDirection() throws SQLException { @Override public void setFetchDirection(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -381,7 +380,7 @@ public int getFetchSize() throws SQLException { @Override public void setFetchSize(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -411,227 +410,227 @@ public boolean rowDeleted() throws SQLException { @Override public void updateNull(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBoolean(int i, boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateByte(int i, byte b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateShort(int i, short i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateInt(int i, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateLong(int i, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateFloat(int i, float v) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateDouble(int i, double v) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBigDecimal(int i, BigDecimal bigDecimal) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateString(int i, String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBytes(int i, byte[] bytes) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateDate(int i, Date date) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateTime(int i, Time time) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateTimestamp(int i, Timestamp timestamp) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateAsciiStream(int i, InputStream inputStream, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBinaryStream(int i, InputStream inputStream, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateCharacterStream(int i, Reader reader, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateObject(int i, Object o, int i1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateObject(int i, Object o) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNull(String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBoolean(String s, boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateByte(String s, byte b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateShort(String s, short i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateInt(String s, int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateLong(String s, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateFloat(String s, float v) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateDouble(String s, double v) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBigDecimal(String s, BigDecimal bigDecimal) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateString(String s, String s1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBytes(String s, byte[] bytes) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateDate(String s, Date date) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateTime(String s, Time time) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateTimestamp(String s, Timestamp timestamp) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateAsciiStream(String s, InputStream inputStream, int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBinaryStream(String s, InputStream inputStream, int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateCharacterStream(String s, Reader reader, int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateObject(String s, Object o, int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateObject(String s, Object o) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void insertRow() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateRow() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void deleteRow() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void refreshRow() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void cancelRowUpdates() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void moveToInsertRow() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void moveToCurrentRow() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -731,42 +730,42 @@ public URL getURL(String s) throws SQLException { @Override public void updateRef(int i, Ref ref) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateRef(String s, Ref ref) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBlob(int i, Blob blob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBlob(String s, Blob blob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateClob(int i, Clob clob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateClob(String s, Clob clob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateArray(int i, Array array) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateArray(String s, Array array) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -781,12 +780,12 @@ public RowId getRowId(String s) throws SQLException { @Override public void updateRowId(int i, RowId rowId) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateRowId(String s, RowId rowId) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -801,22 +800,22 @@ public boolean isClosed() throws SQLException { @Override public void updateNString(int i, String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNString(String s, String s1) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNClob(int i, NClob nClob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNClob(String s, NClob nClob) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -841,12 +840,12 @@ public SQLXML getSQLXML(String s) throws SQLException { @Override public void updateSQLXML(int i, SQLXML sqlxml) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateSQLXML(String s, SQLXML sqlxml) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -871,142 +870,142 @@ public Reader getNCharacterStream(String s) throws SQLException { @Override public void updateNCharacterStream(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNCharacterStream(String s, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateAsciiStream(int i, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBinaryStream(int i, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateCharacterStream(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateAsciiStream(String s, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBinaryStream(String s, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateCharacterStream(String s, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBlob(int i, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBlob(String s, InputStream inputStream, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateClob(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateClob(String s, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNClob(int i, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNClob(String s, Reader reader, long l) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNCharacterStream(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNCharacterStream(String s, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateAsciiStream(int i, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBinaryStream(int i, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateCharacterStream(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateAsciiStream(String s, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBinaryStream(String s, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateCharacterStream(String s, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBlob(int i, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateBlob(String s, InputStream inputStream) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateClob(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateClob(String s, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNClob(int i, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void updateNClob(String s, Reader reader) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java index 7e81d2e49b1..3f62d04786a 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightStatement.java @@ -67,7 +67,6 @@ public int executeUpdate(String s) throws SQLException { @Override public void close() throws SQLException { - } @Override @@ -87,12 +86,12 @@ public int getMaxRows() throws SQLException { @Override public void setMaxRows(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void setEscapeProcessing(boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -102,12 +101,12 @@ public int getQueryTimeout() throws SQLException { @Override public void setQueryTimeout(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void cancel() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -117,12 +116,11 @@ public SQLWarning getWarnings() throws SQLException { @Override public void clearWarnings() throws SQLException { - } @Override public void setCursorName(String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -152,7 +150,7 @@ public int getFetchDirection() throws SQLException { @Override public void setFetchDirection(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -162,7 +160,7 @@ public int getFetchSize() throws SQLException { @Override public void setFetchSize(int i) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override @@ -177,17 +175,17 @@ public int getResultSetType() throws SQLException { @Override public void addBatch(String s) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void clearBatch() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public int[] executeBatch() throws SQLException { - return new int[0]; + throw new SQLFeatureNotSupportedException(); } @Override @@ -252,12 +250,12 @@ public boolean isPoolable() throws SQLException { @Override public void setPoolable(boolean b) throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override public void closeOnCompletion() throws SQLException { - + throw new SQLFeatureNotSupportedException(); } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java index 3c11f800d80..a1f3addd161 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java @@ -31,7 +31,7 @@ public class ResultSetHelper { /** Convert value to String. */ public static String getString(final Object value) throws SQLException { - return String.valueOf(value); + return value == null ? null : String.valueOf(value); } /** Convert value to boolean. */ diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java index c2842746a62..18208b4575a 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java @@ -32,7 +32,7 @@ public class ResultSetHelperTest { @Test public void testString() throws SQLException { - assertEquals(null, ResultSetHelper.getString(null)); + assertNull(ResultSetHelper.getString(null)); assertEquals("a", ResultSetHelper.getString("a")); assertEquals("123", ResultSetHelper.getString(123)); } From 78b308332861486c75f2de729097149c1e639031 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Mon, 3 Feb 2020 09:46:07 -0700 Subject: [PATCH 07/11] Fix mvn verify issues --- java/flight/flight-jdbc/pom.xml | 37 ++++++++++++++++++- .../apache/arrow/jdbc/ResultSetHelper.java | 15 +++++++- .../org/apache/arrow/jdbc/DriverTest.java | 7 ++-- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/java/flight/flight-jdbc/pom.xml b/java/flight/flight-jdbc/pom.xml index e77c0b1e291..3d8bdc9522d 100644 --- a/java/flight/flight-jdbc/pom.xml +++ b/java/flight/flight-jdbc/pom.xml @@ -37,8 +37,43 @@ org.apache.arrow - flight-grpc + arrow-memory ${project.version} + compile + + + org.apache.arrow + arrow-vector + ${project.version} + compile + + + io.grpc + grpc-api + ${dep.grpc.version} + + + io.grpc + grpc-stub + ${dep.grpc.version} + + + io.grpc + grpc-protobuf + ${dep.grpc.version} + + + com.google.protobuf + protobuf-java + ${dep.protobuf.version} + + + com.google.guava + guava + + + org.slf4j + slf4j-api diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java index a1f3addd161..17261748b51 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java @@ -43,7 +43,7 @@ public static boolean getBoolean(final Object value) throws SQLException { } else if (value instanceof String) { return ((String) value).equalsIgnoreCase("true"); } else { - throw new SQLException(); + throw unsupportedConversion("boolean", value); } } @@ -59,7 +59,13 @@ public static short getShort(final Object value) throws SQLException { /** Convert value to int. */ public static int getInt(final Object value) throws SQLException { - throw new SQLFeatureNotSupportedException(); + if (value == null) { + return 0; + } else if (value instanceof Integer) { + return (Integer) value; + } else { + throw unsupportedConversion("int", value); + } } /** Convert value to String. */ @@ -102,4 +108,9 @@ public static Timestamp getTimestamp(final Object value) throws SQLException { throw new SQLFeatureNotSupportedException(); } + /** Convenience method for building an exception for unsupported conversions. */ + private static SQLException unsupportedConversion(String t, Object value) { + return new SQLException("Cannot convert value '" + value + "' to type " + t); + + } } diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index 8f416f10318..0d8c117fffb 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -25,7 +25,6 @@ import java.sql.Statement; import java.util.Properties; -import org.junit.Ignore; import org.junit.Test; /** @@ -50,14 +49,16 @@ public void rejectsNullUrl() throws SQLException { assertFalse(driver.acceptsURL(null)); } - @Ignore + /** + * Note that this is a manual integration test that requires the Rust flight-server example to be running. + */ @Test public void executeQuery() throws SQLException { try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { try (Statement stmt = conn.createStatement()) { try (ResultSet rs = stmt.executeQuery("SELECT id FROM alltypes_plain")) { assertTrue(rs.next()); - assertEquals(1, rs.getInt(1)); + assertEquals(5, rs.getInt(1)); } } } From ba9fd9f29d457a91a24caa28821f3a132df446e5 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Mon, 3 Feb 2020 09:56:25 -0700 Subject: [PATCH 08/11] ignore test --- .../src/test/java/org/apache/arrow/jdbc/DriverTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index 0d8c117fffb..4b1cc17330c 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -25,6 +25,7 @@ import java.sql.Statement; import java.util.Properties; +import org.junit.Ignore; import org.junit.Test; /** @@ -52,6 +53,7 @@ public void rejectsNullUrl() throws SQLException { /** * Note that this is a manual integration test that requires the Rust flight-server example to be running. */ + @Ignore @Test public void executeQuery() throws SQLException { try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { From 767e9e7a9a6e0086f8cd342dc6b11387a602dab3 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Mon, 3 Feb 2020 10:30:38 -0700 Subject: [PATCH 09/11] Implement ResultSet.next() and more data type conversion logic --- .../apache/arrow/jdbc/FlightResultSet.java | 41 ++++++++---- .../apache/arrow/jdbc/ResultSetHelper.java | 63 ++++++++++++++++--- .../org/apache/arrow/jdbc/DriverTest.java | 13 +++- .../arrow/jdbc/ResultSetHelperTest.java | 9 ++- 4 files changed, 102 insertions(+), 24 deletions(-) diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java index b97d978cc94..7bd4a826b6e 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java @@ -27,6 +27,7 @@ import java.sql.Date; import java.sql.NClob; import java.sql.Ref; +import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.RowId; import java.sql.SQLException; @@ -52,10 +53,15 @@ public class FlightResultSet implements java.sql.ResultSet { */ private final FlightStream stream; + /** The current record batch. */ private VectorSchemaRoot root; + private int batchIndex; + private boolean wasNull; + private int rowIndex = -1; + /** * Create a ResultSet to wrap a FlightStream. */ @@ -69,13 +75,24 @@ public FlightResultSet(final FlightStream stream) { @Override public boolean next() throws SQLException { - //TODO - return true; + if (batchIndex < root.getRowCount()) { + batchIndex++; + rowIndex++; + return true; + } else if (stream.next()) { + this.root = stream.getRoot(); + batchIndex = 0; + rowIndex++; + return true; + } else { + this.root = null; + return false; + } } @Override - public Object getObject(int i) throws SQLException { - final Object value = this.root.getFieldVectors().get(i - 1).getObject(i); + public Object getObject(int columnIndex) throws SQLException { + final Object value = this.root.getFieldVectors().get(columnIndex - 1).getObject(batchIndex); this.wasNull = value == null; return value; } @@ -295,7 +312,7 @@ public Reader getCharacterStream(String s) throws SQLException { @Override public BigDecimal getBigDecimal(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getBigDecimal(getObject(i)); } @Override @@ -305,7 +322,7 @@ public BigDecimal getBigDecimal(String s) throws SQLException { @Override public boolean isBeforeFirst() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return rowIndex < 0; } @Override @@ -315,7 +332,7 @@ public boolean isAfterLast() throws SQLException { @Override public boolean isFirst() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return rowIndex == 0; } @Override @@ -345,7 +362,7 @@ public boolean last() throws SQLException { @Override public int getRow() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return rowIndex; } @Override @@ -365,12 +382,14 @@ public boolean previous() throws SQLException { @Override public int getFetchDirection() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSet.FETCH_FORWARD; } @Override - public void setFetchDirection(int i) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public void setFetchDirection(int fetchDirection) throws SQLException { + if (fetchDirection != ResultSet.FETCH_FORWARD) { + throw new SQLFeatureNotSupportedException(); + } } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java index 17261748b51..220decb95a5 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/ResultSetHelper.java @@ -49,20 +49,38 @@ public static boolean getBoolean(final Object value) throws SQLException { /** Convert value to byte. */ public static byte getByte(final Object value) throws SQLException { - throw new SQLFeatureNotSupportedException(); + if (value == null) { + return 0; + } else if (value instanceof Number) { + return ((Number) value).byteValue(); + } else if (value instanceof String) { + return Byte.parseByte((String) value); + } else { + throw unsupportedConversion("byte", value); + } } /** Convert value to short. */ public static short getShort(final Object value) throws SQLException { - throw new SQLFeatureNotSupportedException(); + if (value == null) { + return 0; + } else if (value instanceof Number) { + return ((Number) value).shortValue(); + } else if (value instanceof String) { + return Short.parseShort((String) value); + } else { + throw unsupportedConversion("short", value); + } } /** Convert value to int. */ public static int getInt(final Object value) throws SQLException { if (value == null) { return 0; - } else if (value instanceof Integer) { - return (Integer) value; + } else if (value instanceof Number) { + return ((Number) value).intValue(); + } else if (value instanceof String) { + return Integer.parseInt((String) value); } else { throw unsupportedConversion("int", value); } @@ -70,17 +88,41 @@ public static int getInt(final Object value) throws SQLException { /** Convert value to String. */ public static long getLong(final Object value) throws SQLException { - throw new SQLFeatureNotSupportedException(); + if (value == null) { + return 0; + } else if (value instanceof Number) { + return ((Number) value).longValue(); + } else if (value instanceof String) { + return Long.parseLong((String) value); + } else { + throw unsupportedConversion("long", value); + } } /** Convert value to float. */ public static float getFloat(final Object value) throws SQLException { - throw new SQLFeatureNotSupportedException(); + if (value == null) { + return 0; + } else if (value instanceof Number) { + return ((Number) value).floatValue(); + } else if (value instanceof String) { + return Float.parseFloat((String) value); + } else { + throw unsupportedConversion("float", value); + } } /** Convert value to double. */ public static double getDouble(final Object value) throws SQLException { - throw new SQLFeatureNotSupportedException(); + if (value == null) { + return 0; + } else if (value instanceof Number) { + return ((Number) value).doubleValue(); + } else if (value instanceof String) { + return Double.parseDouble((String) value); + } else { + throw unsupportedConversion("double", value); + } } /** Convert value to BigDecimal. */ @@ -110,7 +152,10 @@ public static Timestamp getTimestamp(final Object value) throws SQLException { /** Convenience method for building an exception for unsupported conversions. */ private static SQLException unsupportedConversion(String t, Object value) { - return new SQLException("Cannot convert value '" + value + "' to type " + t); - + if (value == null) { + return new SQLException(String.format("Cannot convert null value to type %s", t)); + } else { + return new SQLException(String.format("Cannot convert %s value '%s' to type %s", value.getClass(), value, t)); + } } } diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index 4b1cc17330c..72614fa92c5 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -23,11 +23,15 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; import org.junit.Ignore; import org.junit.Test; +import com.google.common.collect.ImmutableList; + /** * JDBC Driver unit tests. */ @@ -53,14 +57,17 @@ public void rejectsNullUrl() throws SQLException { /** * Note that this is a manual integration test that requires the Rust flight-server example to be running. */ - @Ignore @Test + @Ignore public void executeQuery() throws SQLException { try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { try (Statement stmt = conn.createStatement()) { try (ResultSet rs = stmt.executeQuery("SELECT id FROM alltypes_plain")) { - assertTrue(rs.next()); - assertEquals(5, rs.getInt(1)); + List ids = new ArrayList<>(); + while (rs.next()) { + ids.add(rs.getInt(1)); + } + assertEquals(ImmutableList.of(5, 6, 7, 2, 3, 0, 1, 0), ids); } } } diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java index 18208b4575a..22c71eaadd5 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/ResultSetHelperTest.java @@ -31,10 +31,17 @@ public class ResultSetHelperTest { //TODO add exhaustive tests based on suggested conversions in JDBC specification @Test - public void testString() throws SQLException { + public void getString() throws SQLException { assertNull(ResultSetHelper.getString(null)); assertEquals("a", ResultSetHelper.getString("a")); assertEquals("123", ResultSetHelper.getString(123)); } + @Test + public void getInt() throws SQLException { + assertEquals(0, ResultSetHelper.getInt(null)); + assertEquals(123, ResultSetHelper.getInt("123")); + assertEquals(123, ResultSetHelper.getInt(123)); + } + } From 3e174d2df0bcac9afde6b02c7a0146ccc0fdb998 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Mon, 3 Feb 2020 14:45:51 -0700 Subject: [PATCH 10/11] ResultSetMetaData and bug fixes --- .../apache/arrow/jdbc/FlightResultSet.java | 55 +++--- .../arrow/jdbc/FlightResultSetMetaData.java | 156 ++++++++++++++++++ .../org/apache/arrow/jdbc/DriverTest.java | 10 +- 3 files changed, 199 insertions(+), 22 deletions(-) create mode 100644 java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSetMetaData.java diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java index 7bd4a826b6e..f852d934d99 100644 --- a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSet.java @@ -48,44 +48,55 @@ */ public class FlightResultSet implements java.sql.ResultSet { - /** - * Stream of RecordBatch. - */ + /** Stream of RecordBatch instances. */ private final FlightStream stream; /** The current record batch. */ private VectorSchemaRoot root; + /** Current row index into the current batch. */ private int batchIndex; - private boolean wasNull; - + /** Current row index into the stream. */ private int rowIndex = -1; + /** Cache whether the last accessor method encountered a null value. */ + private boolean wasNull; + /** * Create a ResultSet to wrap a FlightStream. */ public FlightResultSet(final FlightStream stream) { this.stream = stream; - if (stream.next()) { - this.root = stream.getRoot(); - } + // fetch the first batch right away so we have meta-data + getNextBatch(); } @Override public boolean next() throws SQLException { - if (batchIndex < root.getRowCount()) { + if (batchIndex + 1 == root.getRowCount()) { + if (getNextBatch()) { + batchIndex++; + rowIndex++; + return true; + } else { + return false; + } + } else { batchIndex++; rowIndex++; return true; - } else if (stream.next()) { - this.root = stream.getRoot(); - batchIndex = 0; - rowIndex++; + } + } + + private boolean getNextBatch() { + batchIndex = -1; + if (stream.next()) { + root = stream.getRoot(); return true; } else { - this.root = null; + root = null; return false; } } @@ -151,8 +162,9 @@ public double getDouble(int i) throws SQLException { return ResultSetHelper.getDouble(getObject(i)); } + @Deprecated @Override - public BigDecimal getBigDecimal(int i, int i1) throws SQLException { + public BigDecimal getBigDecimal(int i, int scale) throws SQLException { throw new SQLFeatureNotSupportedException(); } @@ -231,8 +243,9 @@ public double getDouble(String columnName) throws SQLException { return ResultSetHelper.getDouble(getObject(columnName)); } + @Deprecated @Override - public BigDecimal getBigDecimal(String columnName, int i) throws SQLException { + public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { throw new SQLFeatureNotSupportedException(); } @@ -243,12 +256,12 @@ public byte[] getBytes(String columnName) throws SQLException { @Override public Date getDate(String columnName) throws SQLException { - throw new SQLFeatureNotSupportedException(); + return ResultSetHelper.getDate(getObject(columnName)); } @Override - public Time getTime(String s) throws SQLException { - throw new SQLFeatureNotSupportedException(); + public Time getTime(String columnName) throws SQLException { + return ResultSetHelper.getTime(getObject(columnName)); } @Override @@ -273,7 +286,7 @@ public InputStream getBinaryStream(String columnName) throws SQLException { @Override public SQLWarning getWarnings() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return null; } @Override @@ -287,7 +300,7 @@ public String getCursorName() throws SQLException { @Override public ResultSetMetaData getMetaData() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return new FlightResultSetMetaData(this.root.getFieldVectors()); } @Override diff --git a/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSetMetaData.java b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSetMetaData.java new file mode 100644 index 00000000000..f3c1d7cfa06 --- /dev/null +++ b/java/flight/flight-jdbc/src/main/java/org/apache/arrow/jdbc/FlightResultSetMetaData.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.jdbc; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Types; +import java.util.List; + +import org.apache.arrow.vector.FieldVector; + +/** ResultSetMetaData. */ +public class FlightResultSetMetaData implements ResultSetMetaData { + + private final List fields; + + public FlightResultSetMetaData(final List fields) { + this.fields = fields; + } + + @Override + public int getColumnCount() throws SQLException { + return fields.size(); + } + + @Override + public boolean isAutoIncrement(int i) throws SQLException { + return false; + } + + @Override + public boolean isCaseSensitive(int i) throws SQLException { + return false; + } + + @Override + public boolean isSearchable(int i) throws SQLException { + return false; + } + + @Override + public boolean isCurrency(int i) throws SQLException { + return false; + } + + @Override + public int isNullable(int i) throws SQLException { + return ResultSetMetaData.columnNullable; + } + + @Override + public boolean isSigned(int i) throws SQLException { + return true; + } + + @Override + public int getColumnDisplaySize(int i) throws SQLException { + return 0; + } + + @Override + public String getColumnLabel(int i) throws SQLException { + return null; + } + + @Override + public String getColumnName(int i) throws SQLException { + return fields.get(i - 1).getName(); + } + + @Override + public String getSchemaName(int i) throws SQLException { + return null; + } + + @Override + public int getPrecision(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getScale(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getTableName(int i) throws SQLException { + return null; + } + + @Override + public String getCatalogName(int i) throws SQLException { + return null; + } + + @Override + public int getColumnType(int i) throws SQLException { + switch (fields.get(i - 1).getMinorType()) { + case INT: + return Types.INTEGER; + default: + return Types.OTHER; + } + } + + @Override + public String getColumnTypeName(int i) throws SQLException { + return String.valueOf(fields.get(i - 1).getMinorType()); + } + + @Override + public boolean isReadOnly(int i) throws SQLException { + return false; + } + + @Override + public boolean isWritable(int i) throws SQLException { + return false; + } + + @Override + public boolean isDefinitelyWritable(int i) throws SQLException { + return false; + } + + @Override + public String getColumnClassName(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T unwrap(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isWrapperFor(Class aClass) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index 72614fa92c5..aec1253cc5f 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -21,8 +21,10 @@ import java.sql.Connection; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Types; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -63,11 +65,17 @@ public void executeQuery() throws SQLException { try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { try (Statement stmt = conn.createStatement()) { try (ResultSet rs = stmt.executeQuery("SELECT id FROM alltypes_plain")) { + + ResultSetMetaData md = rs.getMetaData(); + assertEquals(1, md.getColumnCount()); + assertEquals("c0", md.getColumnName(1)); + assertEquals(Types.INTEGER, md.getColumnType(1)); + List ids = new ArrayList<>(); while (rs.next()) { ids.add(rs.getInt(1)); } - assertEquals(ImmutableList.of(5, 6, 7, 2, 3, 0, 1, 0), ids); + assertEquals(ImmutableList.of(4, 5, 6, 7, 2, 3, 0, 1), ids); } } } From 3abf8bbf2cbb7b10939cfcf70307a8106e6e1ae1 Mon Sep 17 00:00:00 2001 From: Andy Grove Date: Mon, 3 Feb 2020 19:01:18 -0700 Subject: [PATCH 11/11] Add java.sql.Driver --- dev/release/rat_exclude_files.txt | 1 + .../src/main/resources/META-INF/services/java.sql.Driver | 1 + .../src/test/java/org/apache/arrow/jdbc/DriverTest.java | 3 ++- java/pom.xml | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 java/flight/flight-jdbc/src/main/resources/META-INF/services/java.sql.Driver diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt index ea54278ede7..5b29f39214e 100644 --- a/dev/release/rat_exclude_files.txt +++ b/dev/release/rat_exclude_files.txt @@ -232,3 +232,4 @@ r/vignettes/*.Rmd ruby/red-arrow/.yardopts rust/arrow/test/data/*.csv rust/rust-toolchain +java/flight/flight-jdbc/src/main/resources/META-INF/services/java.sql.Driver diff --git a/java/flight/flight-jdbc/src/main/resources/META-INF/services/java.sql.Driver b/java/flight/flight-jdbc/src/main/resources/META-INF/services/java.sql.Driver new file mode 100644 index 00000000000..df3a575ba1d --- /dev/null +++ b/java/flight/flight-jdbc/src/main/resources/META-INF/services/java.sql.Driver @@ -0,0 +1 @@ +org.apache.arrow.jdbc.Driver \ No newline at end of file diff --git a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java index aec1253cc5f..904c3920f58 100644 --- a/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java +++ b/java/flight/flight-jdbc/src/test/java/org/apache/arrow/jdbc/DriverTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.*; import java.sql.Connection; +import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -62,7 +63,7 @@ public void rejectsNullUrl() throws SQLException { @Test @Ignore public void executeQuery() throws SQLException { - try (Connection conn = driver.connect("jdbc:arrow://localhost:50051", new Properties())) { + try (Connection conn = DriverManager.getConnection("jdbc:arrow://localhost:50051", new Properties())) { try (Statement stmt = conn.createStatement()) { try (ResultSet rs = stmt.executeQuery("SELECT id FROM alltypes_plain")) { diff --git a/java/pom.xml b/java/pom.xml index dc162768fcb..4aadde92c23 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -137,6 +137,7 @@ **/client/build/** **/*.tbl **/*.iml + **/java.sql.Driver