| Bug #30858 | ParameterMetaData.getParameterType(int i) returns wrong type for "LIMIT ?" | ||
|---|---|---|---|
| Submitted: | 6 Sep 2007 12:22 | Modified: | 13 Sep 2012 8:34 |
| Reporter: | R. Jäschke | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | Connector / J | Severity: | S2 (Serious) |
| Version: | 3.1, 5.0, 5.1 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | limit, parameter meta data, prepared statement | ||
[6 Sep 2007 13:40]
Mark Matthews
Connector/J doesn't return anything _but_ VARCHAR for getParameterMetadata(), because it doesn't have any parameter metadata information available to it. If anything this is a _server_ change in behavior, because the driver doesn't do anything "special" with a limit clause. Since you tried this with 3.1.14, my guess is server-side prepared statements were used there, and they did the type conversion differently than normal statements, which would be a bug.
[6 Sep 2007 14:09]
R. Jäschke
My server version is 5.0.22-Debian_0ubuntu6.06.2-log, I used the following parameters for the connection (with all three versions of the driver) in the sample code: useUnicode=true characterEncoding=UTF-8 characterSetResults=UTF-8 emulateUnsupportedPstmts=false generateSimpleParameterMetadata=true Without the last option I get no parameter metadata at all. I stumbled accross the problem when switching from 3.1 to 5.0 and suddenly some queries in JSPs broke. In my sample code, removing the last two options I can reproduce the problem: with 3.1 I can set the LIMIT as a string, with 5.* I get a SyntaxErrorException.
[11 Feb 2008 19:12]
Tonci Grgin
Hi and thanks for your report. There is a multitude of things going on here behind the scenes so let's get started: - "Wrong type returned": According to manual, I'd say "Not a bug"; - Fixed BUG#21267, ParameterMetaData throws NullPointerException when prepared SQL actually has a syntax error. Added "generateSimpleParameterMetadata" configuration property, which when set to "true" will generate metadata reflecting VARCHAR for every parameter (the default is "false", which will cause an exception to be thrown if no parameter metadata for the statement is actually available). - When *not using" SS PS: Driver is *not preparing* this statement at all, thus it sends "SELECT CharCol FROM bug30858 LIMIT '2'" to server resulting in error. - When using SS PS (useServerPrepStmts=true) it doesn't actually matter whether parameter is sent as Int or String as server makes necessary adjustments (thus no error): setString 15 Query DROP TABLE IF EXISTS bug30858 15 Query CREATE TABLE bug30858 (Id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, CharCol CHAR(10) DEFAULT NULL) 15 Query INSERT INTO bug30858 VALUES (NULL, 'TEST ROW 1') 15 Query INSERT INTO bug30858 VALUES (NULL, 'TEST ROW 2') 15 Prepare [1] SELECT CharCol FROM bug30858 LIMIT ? 15 Execute [1] SELECT CharCol FROM bug30858 LIMIT '2' 15 Query DROP TABLE IF EXISTS bug30858 and setInt 14 Query DROP TABLE IF EXISTS bug30858 14 Query CREATE TABLE bug30858 (Id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, CharCol CHAR(10) DEFAULT NULL) 14 Query INSERT INTO bug30858 VALUES (NULL, 'TEST ROW 1') 14 Query INSERT INTO bug30858 VALUES (NULL, 'TEST ROW 2') 14 Prepare [1] SELECT CharCol FROM bug30858 LIMIT ? 14 Execute [1] SELECT CharCol FROM bug30858 LIMIT 2 14 Query DROP TABLE IF EXISTS bug30858 So, there is no bug as described. We might discuss whether CS PS should guess which type parameter really is but I don't think Mark would allow this... For me, this is !Bg.
[12 Mar 2008 0:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".

Description: On a query like SELECT 'text' LIMIT ? getParameterType(1) returns "VARCHAR" instead of "UNSIGNED". This was no problem until version 3.1 of the driver, because it accepted string values there (e.g. setString("10") worked). As of 5.0 (and 5.1, too), setString("10") throws an exception. Or more exactly: setString("10") works, but when executing the statement, a com.mysql.jdbc.exceptions.MySQLSyntaxErrorException is thrown: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''10'' at line 1 This is especially bad for JSP programming, since there the params are typically integers packed in strings. Hence, updating MySQL Connector/J from 3.1 to 5.0 breaks statements like <sql:query var="rs" dataSource="${dataSource}"> SELECT foo FROM bar LIMIT ? <sql:param value="${param.limit}" /> </sql:query> I could reproduce this behaviour with version 5.0.7 and 5.1.2; version 3.1.14 returns the wrong type, too, but accepts a string there. Note, that SELECT 'text' LIMIT CAST(? AS SIGNED) does not work, too. How to repeat: System.out.println("preparing statement"); PreparedStatement stmtP = conn.prepareStatement("SELECT 'text' LIMIT ?"); ParameterMetaData meta = stmtP.getParameterMetaData(); for (int i = 1; i <= meta.getParameterCount(); i++) { System.out.println("i = " + i + ", typeName = " + meta.getParameterTypeName(i) + ", type = " + meta.getParameterType(i)); } stmtP.setString(1, "10"); System.out.println("executing query"); ResultSet rst = stmtP.executeQuery(); --------------------------------------- output with version 3.1.14: preparing statement i = 1, typeName = VARCHAR, type = 12 executing query --------------------------------------- output with version 5.0.7 and 5.1.2: preparing statement i = 1, typeName = VARCHAR, type = 12 executing query com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''10'' at line 1 com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''10'' at line 1 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1027) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3361) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3295) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1852) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1975) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2476) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1583) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1725) at tests.database.LimitBug.main(LimitBug.java:41) where line 41 is ResultSet rst = stmtP.executeQuery(); Suggested fix: let getParameterTypeName return the correct type or allow strings for LIMIT queries