[jira] [Commented] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14901184#comment-14901184 ] Angus Smithson commented on HIVE-11748: --- [~spena] - just to be clear, there are two changes to HivePreparedStatement.java, from the diff: {noformat} diff --git jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java index 7687537..c28b7d6 100644 --- jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java +++ jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java @@ -607,7 +607,7 @@ public void setObject(int parameterIndex, Object x) throws SQLException { } else if (x instanceof Character) { setString(parameterIndex, x.toString()); } else if (x instanceof Timestamp) { - setString(parameterIndex, x.toString()); + setTimestamp(parameterIndex, (Timestamp) x); } else if (x instanceof BigDecimal) { setString(parameterIndex, x.toString()); } else { @@ -728,7 +728,7 @@ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLExceptio */ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { -this.parameters.put(parameterIndex, x.toString()); +this.parameters.put(parameterIndex, "'" + x.toString() + "'"); } /* {noformat} The first change makes {{setObject(int parameterIndex, Object x)}} call {{setTimestamp(int parameterIndex, Timestamp x)}} when passed a Timestamp. That change is simply to maintain consistency in future. The second change is modifying {{setTimestamp(int parameterIndex, Timestamp x)}} to quote the value it is passed. Prior to this change it was broken (see the issue description). > HivePreparedStatement's setTimestamp() does not quote value as required > --- > > Key: HIVE-11748 > URL: https://issues.apache.org/jira/browse/HIVE-11748 > Project: Hive > Issue Type: Bug > Components: JDBC >Reporter: Angus Smithson >Assignee: Angus Smithson > Attachments: HIVE-11748.2.patch, HIVE-11748.patch > > > [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp > x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] > does not quote the Timestamp value when generating the HQL statement, > resulting in a HiveSqlException on execution. > h5. Reproducing > If we add the following unit test to > {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: > {code} > @Test > public void testPrepareSetTimestamp() throws SQLException, ParseException { > String sql = String.format("SELECT * FROM %s WHERE c20 = ?", > dataTypeTableName); > try (PreparedStatement ps = con.prepareStatement(sql)) { > Timestamp timestamp = new Timestamp(new > SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); > ps.setTimestamp(1, timestamp); > try (ResultSet resultSet = ps.executeQuery()) { > assertTrue(resultSet.next()); > assertEquals("2013-01-01", resultSet.getString(20)); > } > } > } > {code} > The test fails: > {noformat} > org.apache.hive.service.cli.HiveSQLException: Error while compiling > statement: FAILED: ParseException line 1:55 cannot recognize input near '00' > ':' '00' in expression specification > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) > at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) > at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) > at > org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) > at > org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) > at > org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) > at > org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) > at > org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) > at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:606) > at >
[jira] [Commented] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14852716#comment-14852716 ] Angus Smithson commented on HIVE-11748: --- Thanks for taknig a look [~spena]. I assume you're refering to this part of the diff, in {{setObject(int parameterIndex, Object x)}}? {noformat} } else if (x instanceof Timestamp) { - setString(parameterIndex, x.toString()); + setTimestamp(parameterIndex, (Timestamp) x); } else if (x instanceof BigDecimal) { {noformat} \\ I updated it to call setTimestamp so that if anyone modifies {{setTimestamp(...)}} in future, we get the same behaviour... {code} HivePreparedStatement hps = ; Timestamp timestamp = ; // The following two method calls should result in exactly the same behavior. // The caller should be able to call either, depending on the situation. hps.setObject(1, timestamp); hps.setTimestamp(1, timestamp); {code} Prior to this (HIVE-11748) fix, those two calls resulted in different behavior, which I think constitutes a bug. If we leave {{setObject()}} calling {{setString(...)}} and someone modifies {{setTimestamp(...)}} in future, we are back in a place where each provides different behavior (IMO, a bug). > HivePreparedStatement's setTimestamp() does not quote value as required > --- > > Key: HIVE-11748 > URL: https://issues.apache.org/jira/browse/HIVE-11748 > Project: Hive > Issue Type: Bug > Components: JDBC >Reporter: Angus Smithson >Assignee: Angus Smithson > Attachments: HIVE-11748.2.patch, HIVE-11748.patch > > > [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp > x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] > does not quote the Timestamp value when generating the HQL statement, > resulting in a HiveSqlException on execution. > h5. Reproducing > If we add the following unit test to > {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: > {code} > @Test > public void testPrepareSetTimestamp() throws SQLException, ParseException { > String sql = String.format("SELECT * FROM %s WHERE c20 = ?", > dataTypeTableName); > try (PreparedStatement ps = con.prepareStatement(sql)) { > Timestamp timestamp = new Timestamp(new > SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); > ps.setTimestamp(1, timestamp); > try (ResultSet resultSet = ps.executeQuery()) { > assertTrue(resultSet.next()); > assertEquals("2013-01-01", resultSet.getString(20)); > } > } > } > {code} > The test fails: > {noformat} > org.apache.hive.service.cli.HiveSQLException: Error while compiling > statement: FAILED: ParseException line 1:55 cannot recognize input near '00' > ':' '00' in expression specification > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) > at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) > at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) > at > org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) > at > org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) > at > org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) > at > org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) > at > org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) > at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:606) > at > org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1400) > at com.sun.proxy.$Proxy32.ExecuteStatement(Unknown Source) > at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:246) > at > org.apache.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:378) > at > org.apache.hive.jdbc.HivePreparedStatement.executeQuery(HivePreparedStatement.java:109) > at >
[jira] [Commented] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14745321#comment-14745321 ] Angus Smithson commented on HIVE-11748: --- [~szehon] / [~spena] - are you willing/able to review this change? > HivePreparedStatement's setTimestamp() does not quote value as required > --- > > Key: HIVE-11748 > URL: https://issues.apache.org/jira/browse/HIVE-11748 > Project: Hive > Issue Type: Bug > Components: JDBC >Reporter: Angus Smithson > Attachments: HIVE-11748.2.patch, HIVE-11748.patch > > > [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp > x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] > does not quote the Timestamp value when generating the HQL statement, > resulting in a HiveSqlException on execution. > h5. Reproducing > If we add the following unit test to > {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: > {code} > @Test > public void testPrepareSetTimestamp() throws SQLException, ParseException { > String sql = String.format("SELECT * FROM %s WHERE c20 = ?", > dataTypeTableName); > try (PreparedStatement ps = con.prepareStatement(sql)) { > Timestamp timestamp = new Timestamp(new > SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); > ps.setTimestamp(1, timestamp); > try (ResultSet resultSet = ps.executeQuery()) { > assertTrue(resultSet.next()); > assertEquals("2013-01-01", resultSet.getString(20)); > } > } > } > {code} > The test fails: > {noformat} > org.apache.hive.service.cli.HiveSQLException: Error while compiling > statement: FAILED: ParseException line 1:55 cannot recognize input near '00' > ':' '00' in expression specification > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) > at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) > at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) > at > org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) > at > org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) > at > org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) > at > org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) > at > org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) > at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:606) > at > org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1400) > at com.sun.proxy.$Proxy32.ExecuteStatement(Unknown Source) > at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:246) > at > org.apache.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:378) > at > org.apache.hive.jdbc.HivePreparedStatement.executeQuery(HivePreparedStatement.java:109) > at > org.apache.hive.jdbc.TestJdbcDriver2.testPrepareSetTimestamp(TestJdbcDriver2.java:2395) > {noformat} > The failure is because the following HQL is generated/executed by calling > toString() on the Timestamp value: > {noformat} > SELECT * FROM testdatatypetable WHERE c20 = 2013-01-01 00:00:00.0 > {noformat} > We should be quoting the value of Timestamp.toString(), so that the following > HQL is generated/executed: > {noformat} > SELECT * FROM testdatatypetable WHERE c20 = '2013-01-01 00:00:00.0' > {noformat} -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Updated] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Angus Smithson updated HIVE-11748: -- Attachment: HIVE-11748.2.patch Attaching HIVE-11748.2.patch. - Added support for Timestamp to HivePreparedStatement.setObject(int parameterIndex, Object x) - Added coverage of setTimestamp() and setObject(Timestamp x) to TestJdbcDriver2.testPrepareStatement() - General tidy-up of TestJdbcDriver2.testPrepareStatement() -- fixed resource leaks -- made useful (it was incorrectly passing even if no results returned!) - Rewrote TestJdbcDriver2·testPrepareSetTimestamp() to use Timestamp objects rather than Date. \\ I suggest someone with edit privileges on https://cwiki.apache.org/confluence/display/Hive/HowToContribute changes the [unit tests|https://cwiki.apache.org/confluence/display/Hive/HowToContribute#HowToContribute-UnitTests] section. It's confusing for new contributors. Currently it reads: {noformat} > cd hive-trunk > mvn clean install -DskipTests -Phadoop-1 > mvn test -Dtest=SomeTest -Phadoop-1 {noformat} There isn't a "hive-trunk" anymore. I think\* the correct procedure is: {noformat} mvn clean install -DskipTests -Phadoop-1 cd itests mvn test -Dtest=SomeTest -Phadoop-1 {noformat} _\* This is how I executed TestJdbcDriver2 locally - please comment if there's a better way_ > HivePreparedStatement's setTimestamp() does not quote value as required > --- > > Key: HIVE-11748 > URL: https://issues.apache.org/jira/browse/HIVE-11748 > Project: Hive > Issue Type: Bug > Components: JDBC >Reporter: Angus Smithson >Assignee: Angus Smithson > Attachments: HIVE-11748.2.patch, HIVE-11748.patch > > > [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp > x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] > does not quote the Timestamp value when generating the HQL statement, > resulting in a HiveSqlException on execution. > h5. Reproducing > If we add the following unit test to > {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: > {code} > @Test > public void testPrepareSetTimestamp() throws SQLException, ParseException { > String sql = String.format("SELECT * FROM %s WHERE c20 = ?", > dataTypeTableName); > try (PreparedStatement ps = con.prepareStatement(sql)) { > Timestamp timestamp = new Timestamp(new > SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); > ps.setTimestamp(1, timestamp); > try (ResultSet resultSet = ps.executeQuery()) { > assertTrue(resultSet.next()); > assertEquals("2013-01-01", resultSet.getString(20)); > } > } > } > {code} > The test fails: > {noformat} > org.apache.hive.service.cli.HiveSQLException: Error while compiling > statement: FAILED: ParseException line 1:55 cannot recognize input near '00' > ':' '00' in expression specification > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) > at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) > at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) > at > org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) > at > org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) > at > org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) > at > org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) > at > org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) > at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:606) > at > org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1400) > at com.sun.proxy.$Proxy32.ExecuteStatement(Unknown Source) > at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:246) > at > org.apache.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:378) > at >
[jira] [Commented] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14733905#comment-14733905 ] Angus Smithson commented on HIVE-11748: --- The {{org.apache.hive.hcatalog.api.TestHCatClient.testTableSchemaPropagation}} test failure is unrelated, it was failing prior to my changes. > HivePreparedStatement's setTimestamp() does not quote value as required > --- > > Key: HIVE-11748 > URL: https://issues.apache.org/jira/browse/HIVE-11748 > Project: Hive > Issue Type: Bug > Components: JDBC >Reporter: Angus Smithson > Attachments: HIVE-11748.2.patch, HIVE-11748.patch > > > [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp > x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] > does not quote the Timestamp value when generating the HQL statement, > resulting in a HiveSqlException on execution. > h5. Reproducing > If we add the following unit test to > {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: > {code} > @Test > public void testPrepareSetTimestamp() throws SQLException, ParseException { > String sql = String.format("SELECT * FROM %s WHERE c20 = ?", > dataTypeTableName); > try (PreparedStatement ps = con.prepareStatement(sql)) { > Timestamp timestamp = new Timestamp(new > SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); > ps.setTimestamp(1, timestamp); > try (ResultSet resultSet = ps.executeQuery()) { > assertTrue(resultSet.next()); > assertEquals("2013-01-01", resultSet.getString(20)); > } > } > } > {code} > The test fails: > {noformat} > org.apache.hive.service.cli.HiveSQLException: Error while compiling > statement: FAILED: ParseException line 1:55 cannot recognize input near '00' > ':' '00' in expression specification > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) > at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) > at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) > at > org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) > at > org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) > at > org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) > at > org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) > at > org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) > at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:606) > at > org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1400) > at com.sun.proxy.$Proxy32.ExecuteStatement(Unknown Source) > at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:246) > at > org.apache.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:378) > at > org.apache.hive.jdbc.HivePreparedStatement.executeQuery(HivePreparedStatement.java:109) > at > org.apache.hive.jdbc.TestJdbcDriver2.testPrepareSetTimestamp(TestJdbcDriver2.java:2395) > {noformat} > The failure is because the following HQL is generated/executed by calling > toString() on the Timestamp value: > {noformat} > SELECT * FROM testdatatypetable WHERE c20 = 2013-01-01 00:00:00.0 > {noformat} > We should be quoting the value of Timestamp.toString(), so that the following > HQL is generated/executed: > {noformat} > SELECT * FROM testdatatypetable WHERE c20 = '2013-01-01 00:00:00.0' > {noformat} -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Updated] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Angus Smithson updated HIVE-11748: -- Attachment: HIVE-11748.patch Attaching HIVE-11748.patch. This is similar to the changes under HIVE-11024, which fixed the same bug in setDate(). It simply quotes the value of Timestamp.toString(). {noformat} diff --git jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java index 7687537..81c3d5d 100644 --- jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java +++ jdbc/src/java/org/apache/hive/jdbc/HivePreparedStatement.java @@ -728,7 +728,7 @@ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLExceptio */ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { -this.parameters.put(parameterIndex, x.toString()); +this.parameters.put(parameterIndex, "'" + x.toString() + "'"); } /* {noformat} I've also added a unit test and some Dell SecureWorks license information to the NOTICE file. > HivePreparedStatement's setTimestamp() does not quote value as required > --- > > Key: HIVE-11748 > URL: https://issues.apache.org/jira/browse/HIVE-11748 > Project: Hive > Issue Type: Bug > Components: JDBC >Reporter: Angus Smithson > Attachments: HIVE-11748.patch > > > [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp > x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] > does not quote the Timestamp value when generating the HQL statement, > resulting in a HiveSqlException on execution. > h5. Reproducing > If we add the following unit test to > {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: > {code} > @Test > public void testPrepareSetTimestamp() throws SQLException, ParseException { > String sql = String.format("SELECT * FROM %s WHERE c20 = ?", > dataTypeTableName); > try (PreparedStatement ps = con.prepareStatement(sql)) { > Timestamp timestamp = new Timestamp(new > SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); > ps.setTimestamp(1, timestamp); > try (ResultSet resultSet = ps.executeQuery()) { > assertTrue(resultSet.next()); > assertEquals("2013-01-01", resultSet.getString(20)); > } > } > } > {code} > The test fails: > {noformat} > org.apache.hive.service.cli.HiveSQLException: Error while compiling > statement: FAILED: ParseException line 1:55 cannot recognize input near '00' > ':' '00' in expression specification > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) > at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) > at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) > at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) > at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) > at > org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) > at > org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) > at > org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) > at > org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) > at > org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) > at > org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) > at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:606) > at > org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1400) > at com.sun.proxy.$Proxy32.ExecuteStatement(Unknown Source) > at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:246) > at > org.apache.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:378) > at > org.apache.hive.jdbc.HivePreparedStatement.executeQuery(HivePreparedStatement.java:109) > at > org.apache.hive.jdbc.TestJdbcDriver2.testPrepareSetTimestamp(TestJdbcDriver2.java:2395) > {noformat} > The failure is because the following HQL is generated/executed by calling > toString() on the Timestamp value: > {noformat} > SELECT * FROM %s WHERE c20 = 2013-01-01 00:00:00.0 >
[jira] [Updated] (HIVE-11748) HivePreparedStatement's setTimestamp() does not quote value as required
[ https://issues.apache.org/jira/browse/HIVE-11748?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Angus Smithson updated HIVE-11748: -- Description: [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] does not quote the Timestamp value when generating the HQL statement, resulting in a HiveSqlException on execution. h5. Reproducing If we add the following unit test to {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: {code} @Test public void testPrepareSetTimestamp() throws SQLException, ParseException { String sql = String.format("SELECT * FROM %s WHERE c20 = ?", dataTypeTableName); try (PreparedStatement ps = con.prepareStatement(sql)) { Timestamp timestamp = new Timestamp(new SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); ps.setTimestamp(1, timestamp); try (ResultSet resultSet = ps.executeQuery()) { assertTrue(resultSet.next()); assertEquals("2013-01-01", resultSet.getString(20)); } } } {code} The test fails: {noformat} org.apache.hive.service.cli.HiveSQLException: Error while compiling statement: FAILED: ParseException line 1:55 cannot recognize input near '00' ':' '00' in expression specification at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:205) at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:166) at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:401) at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:310) at org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:1150) at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:1136) at org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:109) at org.apache.hive.service.cli.operation.SQLOperation.runInternal(SQLOperation.java:180) at org.apache.hive.service.cli.operation.Operation.run(Operation.java:257) at org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementInternal(HiveSessionImpl.java:405) at org.apache.hive.service.cli.session.HiveSessionImpl.executeStatementAsync(HiveSessionImpl.java:392) at org.apache.hive.service.cli.CLIService.executeStatementAsync(CLIService.java:261) at org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:509) at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1400) at com.sun.proxy.$Proxy32.ExecuteStatement(Unknown Source) at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:246) at org.apache.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:378) at org.apache.hive.jdbc.HivePreparedStatement.executeQuery(HivePreparedStatement.java:109) at org.apache.hive.jdbc.TestJdbcDriver2.testPrepareSetTimestamp(TestJdbcDriver2.java:2395) {noformat} The failure is because the following HQL is generated/executed by calling toString() on the Timestamp value: {noformat} SELECT * FROM testdatatypetable WHERE c20 = 2013-01-01 00:00:00.0 {noformat} We should be quoting the value of Timestamp.toString(), so that the following HQL is generated/executed: {noformat} SELECT * FROM testdatatypetable WHERE c20 = '2013-01-01 00:00:00.0' {noformat} was: [HivePreparedStatement.setTimestamp(int parameterIndex, Timestamp x)|https://hive.apache.org/javadocs/r1.2.1/api/org/apache/hive/jdbc/HivePreparedStatement.html#setTimestamp(int,%20java.sql.Timestamp)] does not quote the Timestamp value when generating the HQL statement, resulting in a HiveSqlException on execution. h5. Reproducing If we add the following unit test to {{itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java}}: {code} @Test public void testPrepareSetTimestamp() throws SQLException, ParseException { String sql = String.format("SELECT * FROM %s WHERE c20 = ?", dataTypeTableName); try (PreparedStatement ps = con.prepareStatement(sql)) { Timestamp timestamp = new Timestamp(new SimpleDateFormat("-MM-dd").parse("2013-01-01").getTime()); ps.setTimestamp(1, timestamp); try (ResultSet resultSet = ps.executeQuery()) { assertTrue(resultSet.next()); assertEquals("2013-01-01", resultSet.getString(20)); } } } {code} The test fails: {noformat} org.apache.hive.service.cli.HiveSQLException: Error while compiling statement: FAILED: ParseException line 1:55 cannot recognize input near '00' ':' '00' in expression