Bug #77013 | find_closing_quote makes .execute fail with HY000 when a SQL comment has a quote | ||
---|---|---|---|
Submitted: | 12 May 2015 10:28 | Modified: | 7 Aug 2024 3:16 |
Reporter: | Georg Bauhaus | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | Connector / ODBC | Severity: | S3 (Non-critical) |
Version: | 5.3.4 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[12 May 2015 10:28]
Georg Bauhaus
[13 May 2015 6:01]
Chiranjeevi Battula
Hello Georg Bauhaus, Thank you for the bug report. I tried to reproduce the issue at my end using single quote string values but not seeing any issues with data inserting. Could you please list out exact steps you tried out at your end, this would help us to reproduce the issue at our end. Thanks, Chiranjeevi.
[13 May 2015 18:50]
Georg Bauhaus
I have repeated all steps from installing the connector to reproducing the issue once more on a freshly installed system. Just so I understand correctly, I take it you meant a single quote in the programming language string containing a SQL statement, not a quote in some SQL "string" value? 1. The connector was dowloaded from the mysql download site at dev.mysql.com, version 5.3.4 for Debian, mysql-connector-odbc-5.3.4-linux-debian6.0-x86-32bit.tar.gz. (A mac installation uses the same version.) 2. Installation as per the instructions, that is, libraries libmyodbc5?.so were copied into /usr/local/lib. unixodbc is installed. 3. The Unicode ODBC driver has been installed into /etc/odbcinst. A data source Abcdef has been installed in /etc/odbc.ini. 4. I can connect via this ODBC data source Abcdef just fine. isql produces a prompt and I can request data from tables of the database. The other end is a MySQL 5.5 server. Access also works using Python and pyodbc, using the ODBC connector and the same data source. 5. The steps leading to the error, as per Unix script(1): georg@debian:~$ python Python 2.7.9 (default, Mar 1 2015, 18:22:53) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import pyodbc >>> conn = pyodbc.connect("DSN=Abcdef") >>> c = conn.cursor() >>> cmd = """-- add new item's id ... INSERT INTO Example (id) VALUES (?) ... """ >>> c.execute(cmd, (123, )) Traceback (most recent call last): File "<stdin>", line 1, in <module> pyodbc.ProgrammingError: ('The SQL contains 0 parameter markers, but 1 parameters were supplied', 'HY000') >>> georg@debian:~$ exit exit Script done on Wed 13 May 2015 08:33:25 PM CEST
[15 May 2015 13:42]
Chiranjeevi Battula
Hello Georg Bauhaus, Thank you for your feedback. Thank you for providing requested details, I'm still not seeing any issues while inserting data with single quoted strings. Please see test details from my environment. Thanks, Chiranjeevi.
[15 May 2015 13:43]
Chiranjeevi Battula
test results mysql> use test Database changed mysql> select * from a; +----+----------+ | id | txt | +----+----------+ | 1 | chiran | | 2 | chiran's | | 3 | Miller's | +----+----------+ 3 rows in set (0.10 sec) mysql>
[15 May 2015 16:43]
Georg Bauhaus
Hello Chiranjeevi Battula, I need to emphasize that you seem misunderstand: The issue is not a quote in an SQL-"string" as you seem to be assuming. Not at all. The issue is about quotes in SQL *comments* that confuse the ODBC layer. It is about SQL-Text at the programming language level, passed to the ODBC layer to be handled by the MySQL driver, not about SQL-"Strings": not about VARCHAR, not about CHAR. There is no "string" column whatever in the complete table definition, repeated here once more, from the "How to repeat" section of the original report: CREATE TABLE Example (id INTEGER) (Note that the Example table has nothing but a single INTEGER, and no other SQL datatypes are used.) To illustrate further, the statement, again, is one, single SQL statement that spans two (2) lines of text. It has one quote, but do note where the quote is! The quote character is not in any VARCHAR, as you seem to have been assuming. The quote is part of an SQL *comment*. The comment is the first line of the single statement, the line that starts with "-- ", and this comment has the quote, right after the word "object" of the comment, in -> "object's" <-: -- add the new object's identity INSERT INTO Example (id) VALUES (?) The quote is the 22nd character of this statment. Written with line numbers, the single SQL statement has two lines of text: line 1: -- add the new object's identity line 2: INSERT INTO Example (id) VALUES (?) line 1 is the culprit, it has the quote that triggers the issue when passing the entire SQL text in one piece to the ODBC layer. If, for example, the SQL statement text were instead written in a C program for ODBC, It'd be written like this: char* query = "-- add the new object's identity\n" /* note the quote on this "line" */ "INSERT INTO Example (id) VALUES (?)\n"; /* watch out: One (1) C-string, but no (0) SQL-"string"! */ So, 1 C-string, 0 SQL-"strings" involved. But! One quote in the *SQL-comment* part. Similarly, in the original test case, there was 1 Python-string, 0 SQL-"strings". It is repeated here: my_cmd = """-- add the new object's identity INSERT INTO Example (id) VALUES (?) """ In case you don't read Python: the Python-Variable my_cmd is now one Python-string, comprising all text from after the first """ to before the second """. The variable my_cmd will be passed to the ODBC layer. If printed, it will look like this: "-- add the new object's identity\nINSERT INTO Example (id) VALUES (?)\n" Note the newline characters, and note the single quote in the comment part. This is how this programming language string gets passed to the ODBC layer. The ODBC layer is confused by the presence of a quote in a comment.
[16 May 2015 9:35]
Gord Thompson
Here is a test case that recreates the issue using VBScript on Windows: ' start of code Option Explicit Dim con Set con = CreateObject("ADODB.Connection") con.Open _ "Driver={MySQL ODBC 5.3 Unicode Driver};" & _ "Server=localhost;Port=3307;" & _ "User=root;Password=whatever;" & _ "Database=test;" con.Execute _ "DROP PROCEDURE IF EXISTS hypot" con.Execute _ "CREATE PROCEDURE hypot ()" & vbCrLf & _ "BEGIN " & vbCrLf & _ " -- Gord's comment " & vbCrLf & _ " PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypot'; " & vbCrLf & _ " SET @a = 3; " & vbCrLf & _ " SET @b = 4; " & vbCrLf & _ " EXECUTE stmt1 USING @a, @b; " & vbCrLf & _ " DEALLOCATE PREPARE stmt1; " & vbCrLf & _ "END " & vbCrLf & _ "" con.Close ' end of code The above code fails with ... C:\__tmp\bug77013.vbs(12, 1) Microsoft OLE DB Provider for ODBC Drivers: [MySQL][ODBC 5.3(w) Driver][mysqld-5.6.13]SQLBindParameter not used for all parameters ... but if I change the line ... " -- Gord's comment " & vbCrLf & _ ... to ... " -- Gord''s comment " & vbCrLf & _ ... then the code runs fine and the stored procedure is created.
[18 May 2015 6:49]
Chiranjeevi Battula
Hello Georg Bauhaus, Thank you for your feedback. Verified this behavior on Visual Studio 2013 (VB.Net) with MySQL Connector / ODBC 5.3.4. Thanks, Chiranjeevi.
[7 Aug 2024 3:16]
Bogdan Degtyariov
Posted by developer: After parser block was re-worked in the ODBC Driver version 8.0 the issue is no longer repeatable. The test cases pass without problems with any number of single and double quotes in the comment etc.