Skip to content

Commit cd11c7e

Browse files
author
Geert Vanderkelen
committed
BUG19207922: Fix fetching multiple results executing procedures
A stored procedure is generally called or executed using the MySQLCursor.callprc() method. However, there is a need to improve MySQLCursor making it possible to return multiple results when executing stored routines using the execute() method. Test cases were updated.
1 parent c691395 commit cd11c7e

File tree

6 files changed

+42
-6
lines changed

6 files changed

+42
-6
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Full release notes:
1111
v2.0.0a1
1212
========
1313

14+
- BUG19207922: Fix fetching multiple results when executing procedure
1415
- BUG19184025: Fix results containing NULL
1516
- BUG19169990: Fix sending/receiving using compressed connection
1617
- BUG18956789: Fix Django TimeField 00:00:00 converting to MySQL NULL

cpyint

lib/mysql/connector/connection.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,12 @@ def _do_handshake(self):
159159
raise errors.InterfaceError("Failed parsing MySQL version")
160160

161161
version = tuple([int(v) for v in match.groups()[0:3]])
162-
if version < (4, 1):
162+
if b'fabric' in match.group(4).lower():
163+
if version < (1, 4):
164+
raise errors.InterfaceError(
165+
"MySQL Fabric '{0}'' is not supported".format(
166+
handshake['server_version_original']))
167+
elif version < (4, 1):
163168
raise errors.InterfaceError(
164169
"MySQL Version '{0}' is not supported.".format(
165170
handshake['server_version_original']))

lib/mysql/connector/conversion.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ def _bytes_to_mysql(self, value):
185185
"""Convert value to bytes"""
186186
return value
187187

188+
def _bytearray_to_mysql(self, value):
189+
"""Convert value to bytes"""
190+
return str(value)
191+
188192
def _bool_to_mysql(self, value):
189193
"""Convert value to boolean"""
190194
if value:

lib/mysql/connector/cursor.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,19 @@ def _execute_iter(self, query_iter):
434434
given query_iter (result of MySQLConnection.cmd_query_iter()) and
435435
the list of statements that were executed.
436436
"""
437-
if not self._executed_list:
438-
self._executed_list = RE_SQL_SPLIT_STMTS.split(self._executed)
437+
executed_list = RE_SQL_SPLIT_STMTS.split(self._executed)
439438

440-
for stmt in self._executed_list:
439+
i = 0
440+
while True:
441441
result = next(query_iter)
442442
self._reset_result()
443443
self._handle_result(result)
444-
self._executed = stmt
444+
try:
445+
self._executed = executed_list[i].strip()
446+
i += 1
447+
except IndexError:
448+
self._executed = executed_list[0]
449+
445450
yield self
446451

447452
def execute(self, operation, params=None, multi=False):

tests/test_cursor.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import re
4040
import time
4141

42+
from . import PY2
4243
import tests
4344
from mysql.connector import (connection, cursor, errors)
4445

@@ -567,6 +568,26 @@ def test_execute(self):
567568
self._test_execute_cleanup(self.cnx, tbl)
568569
self.cur.close()
569570

571+
self.cur = self.cnx.cursor()
572+
self.cur.execute("DROP PROCEDURE IF EXISTS multi_results")
573+
procedure = (
574+
"CREATE PROCEDURE multi_results () "
575+
"BEGIN SELECT 1; SELECT 'ham'; END"
576+
)
577+
self.cur.execute(procedure)
578+
exp_stmt = "CALL multi_results()"
579+
if not PY2:
580+
exp_stmt = b"CALL multi_results()"
581+
exp_result = [[(1,)], [(u'ham',)]]
582+
results = []
583+
for result in self.cur.execute(exp_stmt, multi=True):
584+
if result.with_rows:
585+
self.assertEqual(exp_stmt, result._executed)
586+
results.append(result.fetchall())
587+
588+
self.assertEqual(exp_result, results)
589+
self.cur.execute("DROP PROCEDURE multi_results")
590+
570591
def test_executemany(self):
571592
"""MySQLCursor object executemany()-method"""
572593
self.check_method(self.cur, 'executemany')

0 commit comments

Comments
 (0)