Bug #57022 | cannot execute a store procedure with output parameters | ||
---|---|---|---|
Submitted: | 25 Sep 2010 19:12 | Modified: | 13 Oct 2010 11:06 |
Reporter: | Alexander Klepinin | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Connector / J | Severity: | S2 (Serious) |
Version: | 5.1.13 | OS: | Any |
Assigned to: | Tony Bedford | CPU Architecture: | Any |
[25 Sep 2010 19:12]
Alexander Klepinin
[27 Sep 2010 6:06]
Tonci Grgin
Hi Alexander and thanks for your report. Bug#56095 was closed, without test case, by the *reporter*, not me so it has nothing to do with your report. From the first look, the problem is in this.Database() ("this" being the connection) which refers to "mysql" which has no such function as you created it in TEST database. Will check on this.
[27 Sep 2010 12:05]
Alexander Klepinin
Hi Tonci, First of all, thanks for quick reply! > Bug#56095 was closed, without test case, by the *reporter*, not me so it has > nothing to do with your report. Ok. I just did my best to make sure that I do not submit bug report for known problem. > From the first look, the problem is in this.Database() ("this" being the > connection) which refers to "mysql" which has no such function as you created > it in TEST database. I would not think that the problem is in this.Database(), because even if you change test scenario to use database TEST1 at the moment of invocation of the procedure, the call still fails. The origin of the problem stays the same: when code tries to get information on stored procedure parameters it does not parse procedure name correctly. So, in fact, there are different ways to reproduce this very bug: 1. use full name to refer to procedure. Here call fails, because name is not split into parts before call to DatabaseMetaData.getProcedureColumns. 2. use quoted name (like `PROC`). Here call fails because at the same very place quotes are not removed before call to DatabaseMetaData.getProcedureColumns. 3. use quoted name, containing dot inside. Here call fails because call to DatabaseMetaData.getProcedureColumns will look procedure in current database (due to detected presence of dot). Concluding, I do not want to interfere with normal work of MySQL development team, but my experisnce (I am also developer, and in my company I am responsible for working with different databases in Java) tells me that the problem is in incorrect processing of full (quoted, dotted) identifier. And definitely I would be glad to assist you in solving this problem. -- Sincerely, Alexander
[4 Oct 2010 10:46]
Tonci Grgin
Alexander, sorry for being late on this but I do not feel all that well and this is deep in code I "messed" with for past few months. I'll try checking this week.
[4 Oct 2010 14:02]
Tonci Grgin
Alexander, when using FUNCTIONS I can not reproduce the problem. Pseudo code: Attach root user to database 1 (test in this case) Drop/create database `TST1` Drop/create fuunction `TST1`.`PROC` CALL `TST1`.`PROC` Actual code: this.stmt = this.conn.createStatement(); this.stmt.executeUpdate("DROP DATABASE IF EXISTS TST1;"); this.stmt.executeUpdate("CREATE DATABASE TST1;"); this.stmt.executeUpdate("DROP FUNCTION IF EXISTS TST1.PROC;"); this.stmt.executeUpdate("CREATE FUNCTION TST1.PROC(a float, b bigint, c int) RETURNS INT NO SQL" + "\nBEGIN" + "\nRETURN a;" + "\nEND"); this.stmt.close(); CallableStatement cStmt = null; cStmt = this.conn.prepareCall("{? = CALL `TST1`.`PROC`(?,?,?)}"); cStmt.registerOutParameter(1, Types.INTEGER); cStmt.setFloat(2, 2); cStmt.setInt(3, 1); cStmt.setInt(4, 1); cStmt.execute(); assertEquals(2f, cStmt.getInt(1), .001); System.out.println("Value should be 2 " + cStmt.getString(1)); assertEquals("java.lang.Integer", cStmt.getObject(1).getClass().getName()); cStmt.close(); Of course, I tested with other names and w/wo backticks, works. 101004 15:41:03 7 Connect root@192.168.1.4 on test 7 Query SHOW COLLATION 7 Query SET character_set_results = NULL 7 Query SET autocommit=1 7 Query SET sql_mode='STRICT_TRANS_TABLES' 7 Query SELECT VERSION() 7 Query DROP DATABASE IF EXISTS TST1 7 Query CREATE DATABASE TST1 7 Query DROP FUNCTION IF EXISTS TST1.PROC 7 Query CREATE FUNCTION TST1.PROC(a float, b bigint, c int) RETURNS INT NO SQL BEGIN RETURN a; END 7 Query SHOW FULL TABLES FROM `INFORMATION_SCHEMA` LIKE 'PARAMETERS' 7 Query SELECT name, type, comment FROM mysql.proc WHERE name like 'PROC' and db <=> 'test' ORDER BY name 7 Query SELECT `TST1`.`PROC`(2.0,1,1) 7 Query SELECT @com_mysql_jdbc_outparam_0 7 Quit When using PROCEDURES, I get the problem reported, and it is where I told you it will be, in this.database() (root is attached to test in url): 13 Query SELECT name, type, comment FROM mysql.proc WHERE name like 'PROC' and db <=> 'test' ORDER BY name Fixing.
[4 Oct 2010 14:28]
Tonci Grgin
As a temporary workaround, please use &noAccessToProcedureBodies=true in your JDBC url.
[4 Oct 2010 16:55]
Tonci Grgin
The fix will be to "sanitize" db.sp call just like in last patch for noAccessToProcedureBodies.
[5 Oct 2010 12:28]
Tonci Grgin
I have a working patch for this situation but it will require more testing on corner cases to make sure it does not need rewriting any time soon.
[5 Oct 2010 12:29]
Tonci Grgin
Preliminary patch, not fully tested yet!
Attachment: bug57022.diff (text/x-diff), 2.83 KiB.
[11 Oct 2010 10:38]
Tonci Grgin
Final patch sent for review.
[13 Oct 2010 10:27]
Tonci Grgin
Pushed up to revision 984.
[13 Oct 2010 11:06]
Tony Bedford
Added an entry to 5.1.14 changelog: Invoking a stored procedure containing output parameters by its full name, where the procedure was located in another database, generated the following exception: Parameter index of 1 is out of range (1, 0)
[16 Nov 2010 19:54]
Ashwin Raj
I used mysql connector/j version 5.1.11 and did not have this problem. The code remaining exactly the same and none of the other project dependencies changing, the code threw an exception around this error as soon as I started using driver version 5.1.13. What seems more surprising is that this concerns a stored procedure in the same database and not even another database! I hope this is researched more and fixed completely. Thanks. Ashwin Raj