Details
-
Bug
-
Status: Closed
-
Critical
-
Resolution: Cannot Reproduce
-
None
Description
Create two tables
DROP TABLE IF EXISTS SEN.VARCHAR_TABLE; CREATE TABLE IF NOT EXISTS SEN.VARCHAR_TABLE( KeyColumn VARCHAR(255) PRIMARY KEY, Column1 VARCHAR(510)); UPSERT INTO SEN.VARCHAR_TABLE VALUES ('One','1');
DROP TABLE IF EXISTS SEN.INTEGER_TABLE; CREATE TABLE IF NOT EXISTS SEN.INTEGER_TABLE( KeyColumn VARCHAR(255) PRIMARY KEY, Column1 INTEGER); UPSERT INTO SEN.INTEGER_TABLE VALUES ('Two',2);
Running these two programs results in several crashes.
1. select a varchar by parameterized statement resulting in
SELECT Column1 FROM SEN.VARCHAR_TABLE WHERE KeyColumn = 'One'
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Statement; public class Hello_World { public static void main(String[] args) throws SQLException { try { Class.forName("org.apache.phoenix.queryserver.client.Driver"); } catch (ClassNotFoundException e) { System.out.println("Where is your PhoenixDriver"); e.printStackTrace(); return; } Connection conn = DriverManager.getConnection("jdbc:phoenix:thin:url=http://192.168.222.52:8765"); conn.setAutoCommit(true); String sqlStmt = "SELECT Column1 FROM SEN.VARCHAR_TABLE WHERE KeyColumn = ?"; System.out.println("SQL Statement:\n\t" + sqlStmt); while(true) { ResultSet rset = null; //Statement stmt = conn.createStatement(); PreparedStatement stmt = conn.prepareStatement(sqlStmt); stmt.setString(1, "One"); ResultSet rs = stmt.executeQuery(); while (rs.next()) { String column1 = rs.getString("column1"); if (!column1.equals("1")) { System.out.println(column1); } } } //conn.close(); } }
2. select an integer by parameterized statement resulting in
SELECT Column1 FROM SEN.INTEGER_TABLE WHERE KeyColumn = 'Two'
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Statement; public class Hello_World { public static void main(String[] args) throws SQLException { try { Class.forName("org.apache.phoenix.queryserver.client.Driver"); } catch (ClassNotFoundException e) { System.out.println("Where is your PhoenixDriver"); e.printStackTrace(); return; } Connection conn = DriverManager.getConnection("jdbc:phoenix:thin:url=http://192.168.222.52:8765"); conn.setAutoCommit(true); String sqlStmt = "SELECT Column1 FROM SEN.INTEGER_TABLE WHERE KeyColumn = ?"; System.out.println("SQL Statement:\n\t" + sqlStmt); while(true) { ResultSet rset = null; //Statement stmt = conn.createStatement(); PreparedStatement stmt = conn.prepareStatement(sqlStmt); stmt.setString(1, "Two"); ResultSet rs = stmt.executeQuery(); while (rs.next()) { int column1 = rs.getInt("column1"); if (column1 != 2) { System.out.println(column1); } } } //conn.close(); } }
There are several crashes (might be preventable by adding a pause in the loops?), but the one relevant to this bug is:
SQL Statement: SELECT Column1 FROM SEN.INTEGER_TABLE WHERE KeyColumn = ? Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number at org.apache.calcite.avatica.util.AbstractCursor$NumberAccessor.getNumber(AbstractCursor.java:661) at org.apache.calcite.avatica.util.AbstractCursor$BigNumberAccessor.getInt(AbstractCursor.java:602) at org.apache.calcite.avatica.AvaticaResultSet.getInt(AvaticaResultSet.java:314) at Hello_World.main(Hello_World.java:36)
where we get a string from SEN.VARCHAR_TABLE while we are querying from the SEN.INTEGER_TABLE.
The queryserver is sending the result set in response to a request made from another connection id. The statement id was not checked but there may have been a statement id collision